Creation - jeremy.andreoletti@ens.fr - 13/04/2020
Load occurrence dataset
occurrence_no record_type reid_no collection_no identified_name identified_rank identified_no
1002162: 1 occ:4678 11942 : 1 52582 : 62 Cetacea indet. : 280 species :2525 36652 : 256
1002163: 1 11943 : 1 47465 : 52 Mysticeti indet. : 147 genus : 726 42971 : 156
1002167: 1 12051 : 1 48093 : 42 Odontoceti indet. : 128 family : 689 42937 : 128
1002169: 1 12057 : 1 75152 : 41 Delphinidae indet. : 102 suborder : 287 42953 : 110
1002202: 1 12058 : 1 47428 : 29 Balaenopteridae indet.: 101 order : 285 42977 : 105
1002203: 1 (Other): 286 48887 : 27 Balaena mysticetus : 82 superfamily: 74 64683 : 87
(Other):4672 NA's :4387 (Other):4425 (Other) :3838 (Other) : 92 (Other):3836
difference accepted_name accepted_rank accepted_no early_interval
:3757 Cetacea : 301 species :2155 36652 : 301 Holocene : 659
recombined as : 312 Odontoceti : 242 family : 804 42937 : 242 Langhian : 353
nomen dubium : 296 Mysticeti : 213 genus : 787 42971 : 213 Burdigalian: 340
subjective synonym of: 120 Balaenopteridae : 169 suborder : 455 42977 : 169 Zanclean : 317
invalid subgroup of : 50 Delphinidae : 113 order : 301 42953 : 113 Tortonian : 307
corrected to : 32 Balaena mysticetus: 88 superfamily: 78 64683 : 88 Priabonian : 227
(Other) : 111 (Other) :3552 (Other) : 98 (Other):3552 (Other) :2475
late_interval max_ma min_ma ref_author ref_pubyr reference_no phylum
:4128 Min. : 0.0117 Min. : 0.000 Uhen : 230 Min. :1818 12148 : 98 Chordata:4678
Langhian : 81 1st Qu.: 3.6000 1st Qu.: 2.588 Bianucci et al. : 122 1st Qu.:1975 24251 : 95
Late Pliocene: 80 Median :11.6200 Median : 5.333 Pilleri : 122 Median :1998 13672 : 74
Messinian : 76 Mean :13.8392 Mean :10.058 Oishi and Hasegawa: 104 Mean :1983 19106 : 68
Serravallian : 52 3rd Qu.:20.4400 3rd Qu.:13.820 Fitzgerald : 98 3rd Qu.:2008 32630 : 61
Tortonian : 29 Max. :66.0000 Max. :47.800 Barnes : 87 Max. :2500 12161 : 60
(Other) : 232 (Other) :3915 (Other):4222
phylum_no class class_no order order_no family family_no
33815:4678 Mammalia:4678 36651:4678 Cetacea:4678 36652:4678 : 837 : 837
Delphinidae : 544 42953 : 544
Balaenopteridae : 399 42977 : 399
NO_FAMILY_SPECIFIED: 382 NF : 382
Ziphiidae : 333 42951 : 333
Basilosauridae : 279 42936 : 279
(Other) :1904 (Other):1904
genus genus_no abund_value abund_unit lng lat
:1701 :1701 Min. : 1.000 :2788 Min. :-179.983 Min. :-70.75
Balaenoptera: 133 36678 : 133 1st Qu.: 1.000 elements : 5 1st Qu.: -76.800 1st Qu.: 25.18
Balaena : 116 36676 : 116 Median : 1.000 fragments : 1 Median : 4.433 Median : 37.08
Mesoplodon : 101 36763 : 101 Mean : 2.527 individuals: 52 Mean : -4.137 Mean : 26.34
Squalodon : 93 36852 : 93 3rd Qu.: 1.000 specimens :1832 3rd Qu.: 26.459 3rd Qu.: 45.28
Basilosaurus: 81 36681 : 81 Max. :537.000 Max. : 179.533 Max. : 82.27
(Other) :2453 (Other):2453 NA's :2786
collection_name collection_subset collection_aka cc
Whaling Survey : 256 Min. : 20 :3285 US :1105
Lee Creek Mine, Yorktown Formation: 62 1st Qu.:18577 Crag d'Anvers : 52 IT : 380
Anvers : 52 Median :55621 Felixstowe : 43 JP : 365
Felixstow : 42 Mean :39910 Wiegerink, Zwillbrock : 41 BE : 241
Zwilbroek : 41 3rd Qu.:59059 Oberschwaben, Wurttemberg : 25 NZ : 167
Orciano Pisano : 29 Max. :78523 Fort 4, Mortsel, Oude God, Oude-God: 15 (Other):2419
(Other) :4196 NA's :4650 (Other) :1217 NA's : 1
state county latlng_basis latlng_precision geogscale
:1909 :3358 : 211 seconds:3372 :3661
California : 271 Calvert : 108 based on nearby landmark: 197 minutes: 471 basin : 47
Maryland : 165 Beaufort : 93 based on political unit : 174 6 : 286 hand sample : 13
Antwerpen : 158 Westmoreland: 80 estimated from map :3104 1 : 122 local area : 388
Virginia : 141 San Diego : 60 stated in text : 947 5 : 107 outcrop : 469
North Carolina: 130 Suffolk : 52 unpublished field data : 45 3 : 103 small collection: 100
(Other) :1904 (Other) : 927 (Other): 217
paleomodel paleolng paleolat geoplate cc.1 protected
: 215 Min. :-178.760 Min. :-70.75 109 : 651 US :1064 :4586
gp_mid:4463 1st Qu.: -69.820 1st Qu.: 18.98 315 : 537 IT : 379 FED: 78
Median : 5.560 Median : 38.41 coordinates not computable using this model: 399 JP : 361 NPS: 14
Mean : -3.457 Mean : 25.77 307 : 360 : 247
3rd Qu.: 22.328 3rd Qu.: 44.53 610 : 335 BE : 238
Max. : 179.610 Max. : 82.27 : 215 (Other):2388
NA's :614 NA's :614 (Other) :2181 NA's : 1
formation stratgroup member stratscale zone localsection
:2219 :4056 :3823 :3062 :4516 :4584
Calvert : 240 Chesapeake: 365 Plum Point : 127 bed : 250 MPL4b/MPL5a: 34 Pisco : 39
Pisco : 85 Jackson : 58 Calvert Beach : 79 formation : 604 N18-N19 : 12 Krkwd : 11
Yorktown: 81 Hawthorn : 42 Eibergen : 43 group : 21 MN 17 : 9 SDgFm : 7
Berchem : 48 Cooper : 17 Bone Valley : 42 group of beds: 324 MN 3 : 8 Fan Delta : 4
Red Crag: 48 Ashiya : 15 Antwerpen Sands: 34 member : 417 MN 14 : 7 Langebaanweg: 4
(Other) :1957 (Other) : 125 (Other) : 530 (Other) : 92 (Other) : 29
localbed localorder regionalsection regionalbed regionalorder
:4593 :4594 :4434 :4439 :4441
2 : 17 bottom to top : 39 Blankenhorn : 2 14 : 45 bottom to top: 237
AGL : 14 no particular order: 43 Panama Canal : 1 12 : 36
SAO : 12 top to bottom : 2 Santa Barbara: 1 10 : 20
1 : 7 Shattuck : 237 13 : 16
MTM : 7 Siwa Oasis : 1 d\x8ec-13: 15
(Other): 28 Waihao River : 2 (Other) : 107
lithdescript
:3701
bluish clayey sand\\r\\n"The Yorktown Formation at Lee Creek... is generally a very muddy quartz sand... shell material and cemented sediment comprise less than 3 percent of\\r\\nmost samples" although there is a "boulder bed" at the top of the formation and a single zone of "extensively leached, partially indurated zone that contains abundant molds of turritellid gastropods and cemented clumps of sediment (Snyder et al. 1983): 62
shelf mudstone : 49
no lithological description given : 41
upper marine molasse : 25
brownish sandy clay : 24
(Other) : 776
lithology1 lithadj1 lithification1 minor_lithology1 fossilsfrom1 lithology2
not reported:1628 :3853 :4320 :4238 :2706 :4473
: 904 blue : 119 lithified : 88 sandy : 171 Y:1972 sandstone : 68
sandstone : 888 glauconitic : 75 poorly lithified: 95 argillaceous,muddy: 62 siltstone : 62
claystone : 340 diatomaceous: 52 unlithified : 175 silty : 56 "limestone" : 17
"limestone" : 186 phosphatic : 40 argillaceous : 48 conglomerate: 14
siltstone : 157 brown : 32 calcareous : 42 "shale" : 12
(Other) : 575 (Other) : 507 (Other) : 61 (Other) : 32
lithadj2 lithification2 minor_lithology2 fossilsfrom2
:4620 :4647 :4659 :4617
tuffaceous,gray : 15 lithified : 11 calcareous : 2 Y: 61
yellow : 14 poorly lithified: 11 calcareous,carbonaceous: 5
black,brown : 5 unlithified : 9 sandy : 7
fine : 5 silty : 2
lenticular,"cross stratification": 2 silty,sandy : 3
(Other) : 17
environment tectonic_setting assembl_comps articulated_parts associated_parts
marine indet. :2005 :4630 :1269 :4583 :4623
: 596 cratonic basin : 7 macrofossils :3220 many: 14 many: 5
coastal indet.: 515 foreland basin : 7 macrofossils,mesofossils : 69 none: 62 none: 11
estuary/bay : 208 passive margin : 32 macrofossils,mesofossils,microfossils: 101 some: 19 some: 39
foreshore : 131 pull-apart basin: 2 macrofossils,microfossils : 12
offshore shelf: 124 mesofossils : 4
(Other) :1099 mesofossils,microfossils : 3
common_body_parts rare_body_parts feed_pred_traces
:4659 :4674 :4634
partial skeletons,teeth,vertebrae,limb elements,plant debris: 4 valves: 4 drill holes : 1
partial skeletons : 3 gastric dissolution: 4
mandibles : 2 tooth marks : 39
partial skulls : 2
shells : 2
(Other) : 6
artifacts pres_mode
:4657 body :1810
stone points,stone tools : 8 body,original phosphate :1446
stone points,stone tools,bone tools,textiles : 6 :1254
stone tools,ceramics,structural remains,historical artifacts: 2 body,original phosphate,anthropogenic: 26
charcoal/hearths : 1 body,anthropogenic : 25
historical artifacts : 1 body,soft parts,original phosphate : 18
(Other) : 3 (Other) : 99
preservation_quality spatial_resolution temporal_resolution lagerstatten concentration orientation
:4424 :4647 :4651 :4672 :4675 :4669
excellent: 89 allochthonous : 3 condensed : 1 conservation: 6 #NOM? : 2 life position: 1
good : 92 autochthonous : 20 snapshot : 9 dispersed: 1 preferred : 6
medium : 42 parautochthonous: 8 time-averaged: 17 random : 2
poor : 17
variable : 14
abund_in_sediment fragmentation bioerosion encrustation collection_type
:4645 :4661 :4675 :4674 : 750
abundant: 6 frequent : 7 none : 1 frequent : 2 archaeological : 70
common : 22 occasional: 10 occasional: 2 occasional: 2 biostratigraphic : 55
rare : 5 general faunal/floral:2656
paleoecologic : 25
taphonomic : 38
taxonomic :1084
collection_methods museum collection_coverage
:3911 :4447 :4501
surface (in situ),field collection : 157 UCMP : 69 some genera : 45
field collection : 138 USNM : 53 some macrofossils : 40
bulk,salvage,surface (float),sieve : 62 LACM : 49 some macrofossils,some microfossils: 20
surface (float),surface (in situ),field collection: 53 LACM,UCMP: 8 some microfossils : 16
surface (float),field collection : 38 FLMNH : 7 all macrofossils,some genera : 14
(Other) : 319 (Other) : 45 (Other) : 42
collection_size rock_censused collectors collection_dates
:4603 :4674 :4642 :4661
1 specimens : 36 2000 kg: 3 Bowman : 6 2014-2016 : 5
0 : 11 5 kg : 1 Dubalen : 5 December 1998: 3
1 individuals: 6 H. Lodge : 4 1899 : 1
185 specimens: 3 Fordyce, Rust, A. Grebneff, and S. Wilson,: 3 1969 : 1
2 specimens : 3 Marasti : 2 1987 : 1
(Other) : 16 (Other) : 16 (Other) : 6
taxon_environment motility life_habit diet
: 774 : 774 :3424 : 774
freshwater : 17 actively mobile:3904 amphibious, depth=surface: 5 carnivore :1604
freshwater,terrestrial: 5 aquatic : 666 carnivore, suspension feeder: 593
marine :1749 aquatic, depth=surface : 583 piscivore : 221
marine,freshwater :2067 piscivore, carnivore : 903
oceanic : 66 suspension feeder : 583
reproduction ontogeny composition
: 774 : 774 : 774
viviparous:3904 modification of parts:3904 hydroxyapatite:3899
phosphatic : 5
Reorder accepted ranks according to classification standard.
[1] "family" "genus" "infraorder" "order" "species" "subfamily" "suborder"
[8] "subspecies" "superfamily" "unranked clade"
Load the list of occurrences with morphological information
Taxon composite..n.y. occ.data.based.on Specimen pbdb_specimen_no pbdb_occurence.number
Aetiocetus_cotylalveus : 1 Min. :0.0000 :60 AMNH 9485 : 1 Min. : 25492 Min. : 68135
Agorophius_pygmaeus : 1 1st Qu.:0.0000 CMM-V-15 : 1 CASG 66660 : 1 1st Qu.: 25706 1st Qu.: 461107
Albertocetus_meffordorum: 1 Median :0.0000 MGGC 8548 : 1 CCNHM-101 : 1 Median : 25922 Median : 487310
Albireo_whistleri : 1 Mean :0.3768 MNHN SAS 933: 1 ChM PV4256 : 1 Mean : 35167 Mean : 631596
Archaeodelphis_patrius : 1 3rd Qu.:1.0000 UCMP 83790 : 1 ChM PV4844 : 1 3rd Qu.: 26035 3rd Qu.: 763082
Ashleycetus_planicapitis: 1 Max. :1.0000 USNM 10484 : 1 CHM_PV_4253: 1 Max. :146940 Max. :1360382
(Other) :63 (Other) : 4 (Other) :63 NA's :56
notes
:62
actually this info relates to the holotype, which is MGGC 8608, but it seems that MGGC 8599 has not been entered : 1
It is unclear which specimen is in the pbdb, both are from the Pisco Formation. This one is the referred specimen, not the holotype (but ir is more complete than the holotype): 1
two specimen numbers in pbdb, but both relate to same specimen : 1
two specimens in database, but one comes from USA, so I selected the one from Peru based on collection info : 1
two specimens in pbdb, unlcear which is which because they belong to the same horizon : 1
(Other) : 2
Combine those taxa with extant taxa to get all the species included in the tree.
taxon min max
Balaena_mysticetus : 1 Min. :0 Min. :0
Balaenoptera_acutorostrata: 1 1st Qu.:0 1st Qu.:0
Balaenoptera_bonaerensis : 1 Median :0 Median :0
Balaenoptera_borealis : 1 Mean :0 Mean :0
Balaenoptera_brydei : 1 3rd Qu.:0 3rd Qu.:0
Balaenoptera_edeni : 1 Max. :0 Max. :0
(Other) :82
taxon min max
Aetiocetus_cotylalveus : 1 Min. : 2.588 Min. : 3.60
Agorophius_pygmaeus : 1 1st Qu.: 7.246 1st Qu.:11.62
Albertocetus_meffordorum: 1 Median :13.820 Median :15.97
Albireo_whistleri : 1 Mean :14.357 Mean :18.28
Archaeodelphis_patrius : 1 3rd Qu.:23.030 3rd Qu.:28.10
Ashleycetus_planicapitis: 1 Max. :41.300 Max. :47.80
(Other) :63
taxon min max
Balaena_mysticetus : 1 Min. : 0.00 Min. : 0.000
Balaenoptera_acutorostrata: 1 1st Qu.: 0.00 1st Qu.: 0.000
Balaenoptera_bonaerensis : 1 Median : 0.00 Median : 0.000
Balaenoptera_borealis : 1 Mean : 6.31 Mean : 8.035
Balaenoptera_brydei : 1 3rd Qu.:11.62 3rd Qu.:13.820
Balaenoptera_edeni : 1 Max. :41.30 Max. :47.800
(Other) :151
Check that the names in the datasets are exactly the same as in the list above.
[1] TRUE
Idem at the generic level for the genus analysis.
taxon min max
Balaena_mysticetus : 1 Min. :0 Min. :0
Balaenoptera_physalus : 1 1st Qu.:0 1st Qu.:0
Berardius_bairdii : 1 Median :0 Median :0
Caperea_marginata : 1 Mean :0 Mean :0
Cephalorhynchus_heavisidii: 1 3rd Qu.:0 3rd Qu.:0
Delphinapterus_leucas : 1 Max. :0 Max. :0
(Other) :35
taxon min max
Aetiocetus_cotylalveus : 1 Min. : 2.588 Min. : 3.60
Agorophius_pygmaeus : 1 1st Qu.: 7.246 1st Qu.:11.62
Albertocetus_meffordorum: 1 Median :13.820 Median :15.97
Albireo_whistleri : 1 Mean :14.960 Mean :18.95
Archaeodelphis_patrius : 1 3rd Qu.:23.030 3rd Qu.:28.10
Ashleycetus_planicapitis: 1 Max. :41.300 Max. :47.80
(Other) :56
taxon min max
Balaena_mysticetus : 1 Min. : 0.000 Min. : 0.000
Balaenoptera_physalus : 1 1st Qu.: 0.000 1st Qu.: 0.000
Berardius_bairdii : 1 Median : 5.333 Median : 7.246
Caperea_marginata : 1 Mean : 9.005 Mean :11.409
Cephalorhynchus_heavisidii: 1 3rd Qu.:15.970 3rd Qu.:20.440
Delphinapterus_leucas : 1 Max. :41.300 Max. :47.800
(Other) :97
Check that the names in the datasets are exactly the same as in the list above.
[1] TRUE
Remove those occurrences from our initial dataset to avoid redundancy.
Explore the dataset
Repartition through time
Full fossil record


\(\to\) Numerous occurrences seem to have the same age interval so in order to avoid clusters let’s draw them uniformly in their stratigraphic range rather than taking the mean.


\(\to\) The repartition seems much smoother now.
Subsampling
These occurrences are too numerous for our current implementation, let’s subsample a fraction of them for now.


\(\to\) The distribution looks similar, with some noise due to higher variance with smaller sample.
Repartition among accepted ranks
Pie chart

\(\to\) Half of the occurrences are identified at the level of the secies and 1/3 at the genus or family.
Some clades are unranked :
Chaeomysticeti Neoceti Panphyseteroidea Pelagiceti Platanidelphidi Squaloceti
26 2 1 1 1 1
Time repartition by rank



\(\to\) Apparent huge cluster of occurrences in recent times, with very precise dating = Artefact due to the “Pull of the Recent” effect ? \(\to\) We decided to remove all Late Pleistocene and Holocene occurrences (thus setting the \(\omega\)-sampling to 0) in order to avoid this bias.

\(\to\) We observe similar trends at each rank, with peaks at ~15My and ~5My.
Redundancy of occurrences with the same accepted name

\(\to\) ~Half of species/genera/subfamilies have only one specimen by accepted name, but it could go up to ~50 within the same species and ~200 occurrences within the same suborder. Those differences will have to be corrected because in our model all species are upposed to have the same abundance (identical sampling rates among branches).
\(\implies\) Our goal now will be to correct this abundance bias.
Time intervals = stratigraphic age uncertainty
Minimum and maximum stratigraphic limits


\(\to\) Most species have a early but not a late stratigraphic limit.
Minimum and maximum ages

Time ranges = duration of the time intervals
Count occurrences by accepted name




\(\to\) Some occurrences have too much age uncertainty, they risk to artificially increase species durations.
Remove occurrences with highly uncertain dating (range > 10My)
[1] 3505 117

Most of occurrences show less than 10 My age uncertainty, let’s try to keep only these ones.




\(\to\) The removal of highly uncertain occurrences seems to be only a little biased, even if uncertainty globally increases with age.




\(\to\) Some species (or other ranks) have several occurrences with several time ranges, let’s combine them into a unique range covering all the others.
Combined time ranges = unique time range for occurrences with the same name (without the biggest ones)




Occurrence density
Density distributions

\(\to\) Density logically increases as taxa ranks increase.
Correlation between time range and age
If we want to correct species abundance differences based on the number of occurrences in the time range (“density”), those factors should not depend on time in order to avoid penalizing periods with higher densities.


\(\to\) It seems that age range varies importantly with time, but when taking the full combined range into account the correlation seems quite weak after the first million years.
Let’s look at the density directly, because this is what is interesting us directly.


\(\to\) The density based on combined ranges is much less time-dependant than the density based on initial range ages. We will therefore use the combined density for our corrections.
Sub-sampling of occurrences with a normalized density along the combined ranges
Compare densities for single vs. combined ranges.


\(\to\) Densities are smaller and more concentrated with the combined ranges (larger time span + less ranges in total because of the collepses into unique ranges).
Compare densities by accepted name count (species only)
Let’s focus now on the occurrences accepted at the species level because they are the one for which we can correct the abundance bias by subsampling the most concentrated combined intervals.


\(\to\) Their is a huge span of densities driven by the number of occurrences for the same species that we can reduce by subsampling the most concentrated intervals.
Impact of correcting subsampling on density distributions (species only)


\(\to\) Subsampling successfully reduces the density span from 2 to 1 order of magnitude.
Impact of subsampling on occurrences repartition (species only)
See what our distributions loook like after subsampling :


\(\to\) Some highly dense cluster became much more similar to the others.


If we superpose these 2 plots :

\(\to\) We get the new species occurrence repartition after subsampling correction, that could be used for doing inference with the occurrence birth-death model.
New developments
Compare with a Poisson sampling process
In order to check if the data fit our assumptions of constant-fossilisation-rate Poisson sampling we compare the observed occurrences distributions with the expected ones. Specifically, we will look at the number of taxa represented by 1, 2, 3, … occurrences and the one that we would expect for a given distribution of combined age ranges (as a proxy for species duration).


In a Poisson process with occurrence sampling rate \(\omega\) and for a given time interval of length \(t\), the probability of observing \(N_t = k\) occurrences is given by the Poisson distribution of mean of parameter \(\omega\times t\) :
\[\mathbb{P}(N_t=k) = e^{-\omega t}\frac{(\omega t)^k}{k!}\]
So in order to have the absolute probability of observing \(N_0 = n\) occurrences we have to integrate over the full distribution of age ranges \(t\), called \(f(t)\) :
\[\mathbb{P}(N_0 = n) = \int_t P(N_t = n) f(t) dt = \int_t e^{-\omega t}\frac{(\omega t)^n}{n!} f(t) dt\]
First, approximate this distribution :

Then integrate and plot the expected distribution for a given omega :

Finally, try to find an \(\omega\) value that approximately fits the first points (the least affected by oversampling biases) and check if the other points follow the expected curve :


\(\implies\) Initial observations really do not fit the expectations, species with more than 5 occurrences must remain very rare ! But our subsampling seems to correct most of this bias.
However, this method requires to make several arbitrary choices that may introduce new biases so we will instead subsample at other levels (palaeontological collection, geological formation). In each case only one occurrence will be sampled for the similarly identified, a process we will refer to as aggregating these occurrences according to the chosen factor.
Aggregate similarly identified occurrences in each collection







\(\to\) Each collection corresponds to a unique time interval (inferred from the unique age mean).
In order to reduce the abundance bias, we may keep only one occurrence for each collection :
\(\to\) Not enough occurrences are removed to make a sufficient difference. If we look at the collection with the highest number of occurrences :
Aprixokogia kelloggi Balaena Balaenoptera acutorostrata Balaenopteridae
1 2 2 2
Balaenula Bohaskaia monodontoides Cetotheriinae Delphinapterus
2 1 1 3
Delphinidae Delphinus Globicephala Gricetoides aurorae
2 2 2 1
Herpetocetinae Herpetocetus sendaicus Herpetocetus transatlanticus Kogia breviceps
1 1 1 1
Kogiidae Kogiinae Kogiopsis floridana Lagenorhynchus
1 2 1 2
Lagenorhynchus harmatuki Megaptera Mesoplodon longirostris Monodon
1 2 2 1
Ninoziphius platyrostris Orycterocetus Physeter macrocephalus Physeteridae
3 1 1 1
Physeterinae Physeterula dubusi Plesiocetus Pliopontos littoralis
2 1 1 1
Pontoporia Pontoporiidae Pseudorca Scaldicetus
1 2 2 1
Stenella Stenella rayi Tursiops Ziphius cavirostris
2 1 2 2
\(\to\) There are very few redundancies among the accepted names in collections so aggregating those won’t reduce the abundance bias.
Instead, we may try to aggregate occurrences with the same accepted name at the level of the geological formation (ie subsample only one for each).
Check that the sampling methods do not introduce biases in the repartition between Odontoceti and Mysticeti
Mystecetes are usually larger than odontocetes, and size is associated with a wider geographic range so since we are subsampling occurrences according to geological formation we may be biasing our data towards more widespread species, therefore towards mystecetes.
Look at the families first :

\(\to\) The family repartitions vary a bit after subsampling, but because of the limited number of species by family the fact that we corrected the oversampling of some species could have a disproportionate effect.
Let’s look rather at a higher taxonomic rank, by importing the topology of cetacean families (from Marx et al. 2016) :
`data_frame()` is deprecated as of tibble 1.1.0.
Please use `tibble()` instead.
[90mThis warning is displayed once every 8 hours.[39m
[90mCall `lifecycle::last_warnings()` to see where this warning was generated.[39m






\(\to\) There is a smaller proportion of archeocete occurrences after either sampling, because a huge cluster is subsampled around 35 My ago, but this effect is expected. However, for the Mysticeti vs. Odotoceti there is no huge apparent bias, especially with the aggregating method.
Faster genus-level analysis
More occurrences remain after aggregating with this new method. Let’s compare again with the theoretical distribution :


\(\to\) The correspondance is much less improved than with species aggregation because some genera have a lot of occurrences due to their high number of species species :
Balaenoptera Kentriodon Mesoplodon Scaldicetus Squalodon
53 27 30 41 40
Removed 2 rows containing missing values (geom_bar).

Removed 2 rows containing missing values (geom_bar).

Removed 2 rows containing missing values (geom_bar).Removed 2 rows containing missing values (geom_bar).

\(\to\) Delimiting by geological plates (+ age) instead of countries (+ age) leads to similar distributions, with a bit more occurrences, so we will keep it.
Conclusions
Achievements :
- It seems possible to adequately reduce the abundance bias by subsampling the most concentrated intervals \(\to\) species only
- Using combined ranges by species appears to be more robust \(\to\) to be confirmed
- Very recent samples may have been dated with a more precise method and contain much more fossils, so they should be removed or treated separatadely \(\to\) additional information needed
Open questions :
- What about other accepted ranks ?
- The problem is that differences in the number of occurrences at higher ranks could be due to differences in individual abundances inside species or due to differences in the number of species inside that group.
- A solution could be to look at the number of species by group based on the indicated species, and include it in the bias correction : homogeneizing the number of occurrences / time unit / number sf species in the group \(\to\) additional data required (ranks classification)
- Why do most occurrences miss a late stratigraphic limit ?
- Some occurrences have very huge time intervals \(\to\) Was is a good idea to remove those >10My ? Should we remove more of them (>5My) ?
LS0tCnRpdGxlOiAiRm9ybWF0IENldGFjZWFucyBEYXRhIgpvdXRwdXQ6CiAgcGRmX2RvY3VtZW50OiAKICAgIGZpZ19oZWlnaHQ6IDUuNQogICAgZmlnX3dpZHRoOiAxMAogICAgdG9jOiB5ZXMKICBodG1sX25vdGVib29rOgogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgaHRtbF9kb2N1bWVudDoKICAgIGZpZ193aWR0aDogMTAKICAgIHRvYzogeWVzCi0tLQoKQ3JlYXRpb24gLSBqZXJlbXkuYW5kcmVvbGV0dGlAZW5zLmZyIC0gMTMvMDQvMjAyMAoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gRkFMU0UpCmBgYAoKYGBge3IgaW5jbHVkZT1GQUxTRX0KbGlicmFyeSgiZ2dwbG90MiIpCmxpYnJhcnkoImRwbHlyIikKbGlicmFyeSgiZ2d0cmVlIikKYGBgCgojIExvYWQgb2NjdXJyZW5jZSBkYXRhc2V0CgpgYGB7cn0KIyBzZXR3ZCgifi9Eb2N1bWVudHMvU2NvbGFpcmUvRU5TL1N0YWdlX00xL0NldGFjZWFucy8iKQojIGNldGFjZWFfcGJkYiA8LSByZWFkLmNzdigiZGF0YS1jZXRhY2VhbnMvY2V0YWNlYV9wYmRiXzA1X0Fwcl8yMDE4LmNzdiIsIHNraXAgPSAxNikKY2V0YWNlYV9wYmRiIDwtIHJlYWQuY3N2MigiZGF0YS1jZXRhY2VhbnMvY2V0YWNlYV9wYmRiXzExX01heV8yMDIwLmNzdiIsIHNraXAgPSAxNykKIyBSZW1vdmUgY29sdW1ucyB3aXRoIG9ubHkgTkFzCmNldGFjZWFfcGJkYiA8LSBjZXRhY2VhX3BiZGJbLGNvbFN1bXMoaXMubmEoY2V0YWNlYV9wYmRiKSkgPCBucm93KGNldGFjZWFfcGJkYildCiMgUmVjb3JkIGNsYXNzeWluZyBudW1iZXJzIGFzIGZhY3RvcnMKY2V0YWNlYV9wYmRiWywgZ3JlcCgiX25vIiwgbmFtZXMoY2V0YWNlYV9wYmRiKSwgdmFsdWUgPSBUKV0gPC0gZGF0YS5mcmFtZShzYXBwbHkoY2V0YWNlYV9wYmRiWywgZ3JlcCgiX25vIiwgbmFtZXMoY2V0YWNlYV9wYmRiKSwgdmFsdWUgPSBUKV0sIGFzLmZhY3RvcikpCiMgUmVjb3JkIG51bWVyaWMgcXVhbnRpdGllcyBhcyBkb3VibGVzCmNldGFjZWFfcGJkYlssIGMoImxhdCIsICJsbmciLCAicGFsZW9sYXQiLCAicGFsZW9sbmciLCAibWluX21hIiwgIm1heF9tYSIpXSA8LSBzYXBwbHkoY2V0YWNlYV9wYmRiWywgYygibGF0IiwgImxuZyIsICJwYWxlb2xhdCIsICJwYWxlb2xuZyIsICJtaW5fbWEiLCAibWF4X21hIildLCBmdW5jdGlvbihjb2wpe2FzLm51bWVyaWMoYXMuY2hhcmFjdGVyKGNvbCkpfSkKc3VtbWFyeShjZXRhY2VhX3BiZGJbZ3JlcCgiY29tbWVudCIsIG5hbWVzKGNldGFjZWFfcGJkYiksIHZhbHVlID0gVCwgaW52ZXJ0PVQpXSkKYGBgCgpgYGB7cn0KaGVhZChjZXRhY2VhX3BiZGIsIDEwKQpgYGAKClJlb3JkZXIgYWNjZXB0ZWQgcmFua3MgYWNjb3JkaW5nIHRvIGNsYXNzaWZpY2F0aW9uIHN0YW5kYXJkLgoKYGBge3J9CmxldmVscyhjZXRhY2VhX3BiZGIkYWNjZXB0ZWRfcmFuaykKY2V0YWNlYV9wYmRiJGFjY2VwdGVkX3JhbmsgPC0gZmFjdG9yKGNldGFjZWFfcGJkYiRhY2NlcHRlZF9yYW5rLCBsZXZlbHM9Yygic3Vic3BlY2llcyIsICJzcGVjaWVzIiwgImdlbnVzIiwgInN1YmZhbWlseSIsICJmYW1pbHkiLCAic3VwZXJmYW1pbHkiLCAiaW5mcmFvcmRlciIsICJzdWJvcmRlciIsICJvcmRlciIsICJ1bnJhbmtlZCBjbGFkZSIpKQpjZXRhY2VhX3BiZGIkaWRlbnRpZmllZF9yYW5rIDwtIGZhY3RvcihjZXRhY2VhX3BiZGIkaWRlbnRpZmllZF9yYW5rLCBsZXZlbHM9Yygic3Vic3BlY2llcyIsICJzcGVjaWVzIiwgImdlbnVzIiwgInN1YmZhbWlseSIsICJmYW1pbHkiLCAic3VwZXJmYW1pbHkiLCAiaW5mcmFvcmRlciIsICJzdWJvcmRlciIsICJvcmRlciIsICJ1bnJhbmtlZCBjbGFkZSIpKQpgYGAKCiMgTG9hZCB0aGUgbGlzdCBvZiBvY2N1cnJlbmNlcyB3aXRoIG1vcnBob2xvZ2ljYWwgaW5mb3JtYXRpb24KCmBgYHtyfQpvY2N1cnJlbmNlc193aXRoX21vcnBob2xvZ3kgPC0gcmVhZC5jc3YyKCJkYXRhLWNldGFjZWFucy9TcGVjaW1lbnNQQkRCX25ld05hbWVzLmNzdiIpCnN1bW1hcnkob2NjdXJyZW5jZXNfd2l0aF9tb3JwaG9sb2d5KQpgYGAKCkNvbWJpbmUgdGhvc2UgdGF4YSB3aXRoIGV4dGFudCB0YXhhIHRvIGdldCBhbGwgdGhlIHNwZWNpZXMgaW5jbHVkZWQgaW4gdGhlIHRyZWUuCgpgYGB7cn0KZXh0YW50X3RheGEgPC0gcmVhZC5jc3YyKCJkYXRhLWNldGFjZWFucy9DZXRhY2VhX2V4dGFudF90YXhhLmNzdiIpCnN1bW1hcnkoZXh0YW50X3RheGEpCmBgYAoKYGBge3J9CmV4dGluY3RfdGF4YSA8LSBjZXRhY2VhX3BiZGJbY2V0YWNlYV9wYmRiJG9jY3VycmVuY2Vfbm8gJWluJSBvY2N1cnJlbmNlc193aXRoX21vcnBob2xvZ3kkcGJkYl9vY2N1cmVuY2UubnVtYmVyLCBjKCJhY2NlcHRlZF9uYW1lIiwgIm1pbl9tYSIsICJtYXhfbWEiKV0KZXh0aW5jdF90YXhhJGFjY2VwdGVkX25hbWUgPC0gYXMuZmFjdG9yKGdzdWIoIiAiLCAiXyIsIGV4dGluY3RfdGF4YSRhY2NlcHRlZF9uYW1lKSkKbmFtZXMoZXh0aW5jdF90YXhhKSA8LSBuYW1lcyhleHRhbnRfdGF4YSkKc3VtbWFyeShleHRpbmN0X3RheGEpCmBgYAoKYGBge3J9CnRheGEgPC0gcmJpbmQoZXh0YW50X3RheGEsIGV4dGluY3RfdGF4YSkKc3VtbWFyeSh0YXhhKQp3cml0ZS50YWJsZSh0YXhhLCBmaWxlID0gImRhdGEtY2V0YWNlYW5zL0NldGFjZWFfdGF4YS5jc3YiLCBxdW90ZSA9IEYsIHNlcD0iXHQiLCByb3cubmFtZXMgPSBGKQpgYGAKCkNoZWNrIHRoYXQgdGhlIG5hbWVzIGluIHRoZSBkYXRhc2V0cyBhcmUgZXhhY3RseSB0aGUgc2FtZSBhcyBpbiB0aGUgbGlzdCBhYm92ZS4KCmBgYHtyfQptb3JwaG9fbmFtZXMgPC0gcmVhZC50YWJsZSgiZGF0YS1jZXRhY2VhbnMvbW9ycGhvX3NpbXBsaWZpZWRfbmV3TmFtZXNfcmVtb3ZlT3V0Z3JvdXBzVW5kZXNjcmliZWQubmV4Iiwgc2tpcD02LCBmaWxsPVQpCm1vcnBob19uYW1lcyA8LSBkcm9wbGV2ZWxzKG1vcnBob19uYW1lcyRWMVtzYXBwbHkobW9ycGhvX25hbWVzJFYxLCBncmVwbCwgcGF0dGVybj0iXyIpXSkKCm1pdF9uYW1lcyA8LSByZWFkLnRhYmxlKCJkYXRhLWNldGFjZWFucy9NNDM3Nl9tdF9zaW1wbGlmaWVkX25ld05hbWVzX3JlbW92ZU91dGdyb3Vwcy5uZXgiLCBza2lwPTYsIGZpbGw9VCkKbWl0X25hbWVzIDwtIGRyb3BsZXZlbHMobWl0X25hbWVzJFYxW3NhcHBseShtaXRfbmFtZXMkVjEsIGdyZXBsLCBwYXR0ZXJuPSJfIildKQoKbnVjX25hbWVzIDwtIHJlYWQudGFibGUoImRhdGEtY2V0YWNlYW5zL000MzU4X251Y2xlYXJfc2ltcGxpZmllZF9uZXdOYW1lc19yZW1vdmVPdXRncm91cHMubmV4Iiwgc2tpcD02LCBmaWxsPVQpCm51Y19uYW1lcyA8LSBkcm9wbGV2ZWxzKG51Y19uYW1lcyRWMVtzYXBwbHkobnVjX25hbWVzJFYxLCBncmVwbCwgcGF0dGVybj0iXyIpXSkKCnNldGVxdWFsKHRheGEkdGF4b24sIHVuaW9uKHVuaW9uKG1vcnBob19uYW1lcywgbWl0X25hbWVzKSwgbnVjX25hbWVzKSkKYGBgCgpJZGVtIGF0IHRoZSBnZW5lcmljIGxldmVsIGZvciB0aGUgZ2VudXMgYW5hbHlzaXMuCgpgYGB7cn0Kb2NjdXJyZW5jZXNfd2l0aF9tb3JwaG9sb2d5X2dlbmVyYSA8LSBvY2N1cnJlbmNlc193aXRoX21vcnBob2xvZ3lbLXdoaWNoKG9jY3VycmVuY2VzX3dpdGhfbW9ycGhvbG9neSRUYXhvbiAlaW4lIGMoIkF0b2NldHVzX25hc2FsaXMiLCAiQnJhY2h5ZGVscGhpc19qYWh1YXllbnNpcyIsICJIYWJvcm9waG9jb2VuYV9taW51dHVzIiwgIkxvcGhvY2V0dXNfcmVwZW5uaW5naSIsICJPZG9iZW5vY2V0b3BzX3BlcnV2aWFudXMiLCAiT3Rla2Fpa2VhX2h1YXRhIiwgIlBhcmFwb250b3BvcmlhX3dpbHNvbmkiKSksXQpleHRhbnRfZ2VuZXJhIDwtIHJlYWQuY3N2MigiZGF0YS1jZXRhY2VhbnMvQ2V0YWNlYV9leHRhbnRfZ2VuZXJhLmNzdiIpCnN1bW1hcnkoZXh0YW50X2dlbmVyYSkKCmV4dGluY3RfZ2VuZXJhIDwtIGNldGFjZWFfcGJkYltjZXRhY2VhX3BiZGIkb2NjdXJyZW5jZV9ubyAlaW4lIG9jY3VycmVuY2VzX3dpdGhfbW9ycGhvbG9neV9nZW5lcmEkcGJkYl9vY2N1cmVuY2UubnVtYmVyLCBjKCJhY2NlcHRlZF9uYW1lIiwgIm1pbl9tYSIsICJtYXhfbWEiKV0KZXh0aW5jdF9nZW5lcmEkYWNjZXB0ZWRfbmFtZSA8LSBhcy5mYWN0b3IoZ3N1YigiICIsICJfIiwgZXh0aW5jdF9nZW5lcmEkYWNjZXB0ZWRfbmFtZSkpCm5hbWVzKGV4dGluY3RfZ2VuZXJhKSA8LSBuYW1lcyhleHRhbnRfZ2VuZXJhKQpzdW1tYXJ5KGV4dGluY3RfZ2VuZXJhKQoKZ2VuZXJhIDwtIHJiaW5kKGV4dGFudF9nZW5lcmEsIGV4dGluY3RfZ2VuZXJhKQpzdW1tYXJ5KGdlbmVyYSkKd3JpdGUudGFibGUoZ2VuZXJhLCBmaWxlID0gImRhdGEtY2V0YWNlYW5zL0NldGFjZWFfZ2VuZXJhLmNzdiIsIHF1b3RlID0gRiwgc2VwPSJcdCIsIHJvdy5uYW1lcyA9IEYpCmBgYAoKQ2hlY2sgdGhhdCB0aGUgbmFtZXMgaW4gdGhlIGRhdGFzZXRzIGFyZSBleGFjdGx5IHRoZSBzYW1lIGFzIGluIHRoZSBsaXN0IGFib3ZlLgoKYGBge3J9Cm1vcnBob19uYW1lc19nZW5lcmEgPC0gcmVhZC50YWJsZSgiZGF0YS1jZXRhY2VhbnMvbW9ycGhvX3NpbXBsaWZpZWRfbmV3TmFtZXNfZ2VuZXJhX3JlbW92ZU91dGdyb3Vwc1VuZGVzY3JpYmVkLm5leCIsIHNraXA9NiwgZmlsbD1UKQptb3JwaG9fbmFtZXNfZ2VuZXJhIDwtIGRyb3BsZXZlbHMobW9ycGhvX25hbWVzX2dlbmVyYSRWMVtzYXBwbHkobW9ycGhvX25hbWVzX2dlbmVyYSRWMSwgZ3JlcGwsIHBhdHRlcm49Il8iKV0pCgptaXRfbmFtZXNfZ2VuZXJhIDwtIHJlYWQudGFibGUoImRhdGEtY2V0YWNlYW5zL000Mzc2X210X3NpbXBsaWZpZWRfbmV3TmFtZXNfZ2VuZXJhX3JlbW92ZU91dGdyb3Vwcy5uZXgiLCBza2lwPTYsIGZpbGw9VCkKbWl0X25hbWVzX2dlbmVyYSA8LSBkcm9wbGV2ZWxzKG1pdF9uYW1lc19nZW5lcmEkVjFbc2FwcGx5KG1pdF9uYW1lc19nZW5lcmEkVjEsIGdyZXBsLCBwYXR0ZXJuPSJfIildKQoKbnVjX25hbWVzX2dlbmVyYSA8LSByZWFkLnRhYmxlKCJkYXRhLWNldGFjZWFucy9NNDM1OF9udWNsZWFyX3NpbXBsaWZpZWRfbmV3TmFtZXNfZ2VuZXJhX3JlbW92ZU91dGdyb3Vwcy5uZXgiLCBza2lwPTYsIGZpbGw9VCkKbnVjX25hbWVzX2dlbmVyYSA8LSBkcm9wbGV2ZWxzKG51Y19uYW1lc19nZW5lcmEkVjFbc2FwcGx5KG51Y19uYW1lc19nZW5lcmEkVjEsIGdyZXBsLCBwYXR0ZXJuPSJfIildKQoKc2V0ZXF1YWwoZ2VuZXJhJHRheG9uLCB1bmlvbih1bmlvbihtb3JwaG9fbmFtZXNfZ2VuZXJhLCBtaXRfbmFtZXNfZ2VuZXJhKSwgbnVjX25hbWVzX2dlbmVyYSkpCmBgYAoKUmVtb3ZlIHRob3NlIG9jY3VycmVuY2VzIGZyb20gb3VyIGluaXRpYWwgZGF0YXNldCB0byBhdm9pZCByZWR1bmRhbmN5LgoKYGBge3J9CmNldGFjZWFfcGJkYiA8LSBjZXRhY2VhX3BiZGJbIShjZXRhY2VhX3BiZGIkb2NjdXJyZW5jZV9ubyAlaW4lIG9jY3VycmVuY2VzX3dpdGhfbW9ycGhvbG9neSRwYmRiX29jY3VyZW5jZS5udW1iZXIpLF0KYGBgCgojIEV4cGxvcmUgdGhlIGRhdGFzZXQKIyMgUmVwYXJ0aXRpb24gdGhyb3VnaCB0aW1lCiMjIyBGdWxsIGZvc3NpbCByZWNvcmQKCmBgYHtyfQojIENvbXB1dGUgdGhlIG1lYW4gYWdlIGluIHRoZSB0aW1lIGludGVydmFsCmNldGFjZWFfcGJkYiRhZ2VfbWVhbiA8LSAoY2V0YWNlYV9wYmRiJG1pbl9tYStjZXRhY2VhX3BiZGIkbWF4X21hKS8yCgpnZ3Bsb3QoY2V0YWNlYV9wYmRiLCBhZXMoeD0tYWdlX21lYW4sIHk9cm5vcm0obGVuZ3RoKGFnZV9tZWFuKSwgMSwgMC4wNSkpKSArCiAgZ2VvbV9wb2ludChjZXg9MC4xLCBhbHBoYT0wLjUpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJUaW1lIChNeSkiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKG5hbWUgPSAiT2NjdXJyZW5jZXMiLCBsaW1pdHMgPSBjKDAuNSwgMS41KSkgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iQWNjZXB0ZWQgcmFuayIpICsKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMubGluZS54ID0gZWxlbWVudF9saW5lKHNpemUgPSAwLjUsIGxpbmV0eXBlID0gInNvbGlkIiwgY29sb3VyID0gImJsYWNrIiksCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpKSArCiAgZ2d0aXRsZShwYXN0ZSgiUmVwYXJ0aXRpb24gb2YiLCBkaW0oY2V0YWNlYV9wYmRiKVsxXSwgInJlY29yZGVkIG9jY3VycmVuY2VzIHRocm91Z2ggdGltZSIpKQoKZ2dwbG90KGNldGFjZWFfcGJkYiwgYWVzKHg9LWFnZV9tZWFuKSkgKwogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMSkgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIlRpbWUgKE15KSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobmFtZSA9ICJOdW1iZXIgb2Ygb2NjdXJyZW5jZXMiKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSJBY2NlcHRlZCByYW5rIikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBsZWdlbmQucG9zaXRpb249ImJvdHRvbSIpICsKICBnZ3RpdGxlKHBhc3RlKCJFdm9sdXRpb24gb2YgdGhlIG51bWJlciBvY2N1cnJlbmNlcyB0aHJvdWdoIHRpbWUgKCB0b3RhbCBvZiIsIGRpbShjZXRhY2VhX3BiZGIpWzFdLCAiKSAtIE1pZHBvaW50IikpCmBgYAoKJFx0byQgTnVtZXJvdXMgb2NjdXJyZW5jZXMgc2VlbSB0byBoYXZlIHRoZSBzYW1lIGFnZSBpbnRlcnZhbCBzbyBpbiBvcmRlciB0byBhdm9pZCBjbHVzdGVycyBsZXQncyBkcmF3IHRoZW0gdW5pZm9ybWx5IGluIHRoZWlyIHN0cmF0aWdyYXBoaWMgcmFuZ2UgcmF0aGVyIHRoYW4gdGFraW5nIHRoZSBtZWFuLgoKYGBge3J9CiMgRHJhdyBvY2N1cnJlbmNlIGFnZSB1bmlmb3JtYWxseSBpbiB0aGUgdGltZSBpbnRlcnZhbApjZXRhY2VhX3BiZGIkYWdlX3J1bmlmIDwtIG1hcHBseShmdW5jdGlvbihtLCBNKXtydW5pZihuPTEsIG1pbj1tLCBtYXg9TSl9LCBjZXRhY2VhX3BiZGIkbWluX21hLCBjZXRhY2VhX3BiZGIkbWF4X21hKQoKZ2dwbG90KGNldGFjZWFfcGJkYiwgYWVzKHg9LWFnZV9ydW5pZiwgeT1ybm9ybShsZW5ndGgoYWdlX3J1bmlmKSwgMSwgMC4wNSkpKSArCiAgZ2VvbV9wb2ludChjZXg9MC4xLCBhbHBoYT0wLjUpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJUaW1lIChNeSkiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKG5hbWUgPSAiT2NjdXJyZW5jZXMiLCBsaW1pdHMgPSBjKDAuNSwgMS41KSkgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iQWNjZXB0ZWQgcmFuayIpICsKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMubGluZS54ID0gZWxlbWVudF9saW5lKHNpemUgPSAwLjUsIGxpbmV0eXBlID0gInNvbGlkIiwgY29sb3VyID0gImJsYWNrIiksCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpKSArCiAgZ2d0aXRsZShwYXN0ZSgiUmVwYXJ0aXRpb24gb2YiLCBkaW0oY2V0YWNlYV9wYmRiKVsxXSwgInJlY29yZGVkIG9jY3VycmVuY2VzIHRocm91Z2ggdGltZSIpKQoKZ2dwbG90KGNldGFjZWFfcGJkYiwgYWVzKHg9LWFnZV9ydW5pZikpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDEpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJUaW1lIChNeSkiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKG5hbWUgPSAiTnVtYmVyIG9mIG9jY3VycmVuY2VzIikgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iQWNjZXB0ZWQgcmFuayIpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJib3R0b20iKSArCiAgZ2d0aXRsZShwYXN0ZSgiRXZvbHV0aW9uIG9mIHRoZSBudW1iZXIgb2NjdXJyZW5jZXMgdGhyb3VnaCB0aW1lICggdG90YWwgb2YiLCBkaW0oY2V0YWNlYV9wYmRiKVsxXSwgIikgLSBVbmlmb3JtIGRyYXciKSkKYGBgCgokXHRvJCBUaGUgcmVwYXJ0aXRpb24gc2VlbXMgbXVjaCBzbW9vdGhlciBub3cuCgojIyMgU3Vic2FtcGxpbmcKClRoZXNlIG9jY3VycmVuY2VzIGFyZSB0b28gbnVtZXJvdXMgZm9yIG91ciBjdXJyZW50IGltcGxlbWVudGF0aW9uLCBsZXQncyBzdWJzYW1wbGUgYSBmcmFjdGlvbiBvZiB0aGVtIGZvciBub3cuCgpgYGB7cn0KY2V0YWNlYV9wYmRiX3N1YnNhbXBsZWQgPC0gc2FtcGxlX24oY2V0YWNlYV9wYmRiLCBzaXplPXJvdW5kKGxlbmd0aChhZ2VfcnVuaWYpKjAuMTApKQoKZ2dwbG90KGNldGFjZWFfcGJkYl9zdWJzYW1wbGVkLCBhZXMoeD0tYWdlX3J1bmlmLCB5PXJub3JtKGxlbmd0aChhZ2VfcnVuaWYpLCAxLCAwLjA1KSkpICsKICBnZW9tX3BvaW50KGNleD0wLjUsIGFscGhhPTAuNSkgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIlRpbWUgKE15KSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobmFtZSA9ICJPY2N1cnJlbmNlcyIsIGxpbWl0cyA9IGMoMC41LCAxLjUpKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSJBY2NlcHRlZCByYW5rIikgKwogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy5saW5lLnggPSBlbGVtZW50X2xpbmUoc2l6ZSA9IDAuNSwgbGluZXR5cGUgPSAic29saWQiLCBjb2xvdXIgPSAiYmxhY2siKSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCkpICsKICBnZ3RpdGxlKHBhc3RlKCJSZXBhcnRpdGlvbiBvZiIsIGRpbShjZXRhY2VhX3BiZGJfc3Vic2FtcGxlZClbMV0sICJyZWNvcmRlZCBvY2N1cnJlbmNlcyB0aHJvdWdoIHRpbWUiKSkKCmdncGxvdChjZXRhY2VhX3BiZGJfc3Vic2FtcGxlZCwgYWVzKHg9LWFnZV9ydW5pZikpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDEpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJUaW1lIChNeSkiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKG5hbWUgPSAiTnVtYmVyIG9mIG9jY3VycmVuY2VzIikgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iQWNjZXB0ZWQgcmFuayIpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJib3R0b20iKSArCiAgZ2d0aXRsZShwYXN0ZSgiRXZvbHV0aW9uIG9mIHRoZSBudW1iZXIgb2NjdXJyZW5jZXMgdGhyb3VnaCB0aW1lICggdG90YWwgb2YiLCBkaW0oY2V0YWNlYV9wYmRiX3N1YnNhbXBsZWQpWzFdLCAiKSAtIFVuaWZvcm0gZHJhdyIpKQpgYGAKCiRcdG8kIFRoZSBkaXN0cmlidXRpb24gbG9va3Mgc2ltaWxhciwgd2l0aCBzb21lIG5vaXNlIGR1ZSB0byBoaWdoZXIgdmFyaWFuY2Ugd2l0aCBzbWFsbGVyIHNhbXBsZS4KCmBgYHtyfQp3cml0ZShjZXRhY2VhX3BiZGIkYWdlX21lYW4sIGZpbGUgPSAiZGF0YS1jZXRhY2VhbnMvQ2V0YWNlYV9vY2N1cnJlbmNlc19tZWFuX2FnZS5jc3YiLCBzZXA9IjsgIiwgbmNvbHVtbnMgPSBkaW0oY2V0YWNlYV9wYmRiKVsxXSkKd3JpdGUoY2V0YWNlYV9wYmRiJGFnZV9ydW5pZiwgZmlsZSA9ICJkYXRhLWNldGFjZWFucy9DZXRhY2VhX2FnZV9ydW5pZl9hZ2UuY3N2Iiwgc2VwPSI7ICIsIG5jb2x1bW5zID0gZGltKGNldGFjZWFfcGJkYilbMV0pCndyaXRlKGNldGFjZWFfcGJkYl9zdWJzYW1wbGVkJGFnZV9ydW5pZiwgZmlsZSA9ICJkYXRhLWNldGFjZWFucy9DZXRhY2VhX2FnZV9ydW5pZl9hZ2Vfc3Vic2FtcGxlZC5jc3YiLCBzZXA9IjsgIiwgbmNvbHVtbnMgPSBkaW0oY2V0YWNlYV9wYmRiX3N1YnNhbXBsZWQpWzFdKQpgYGAKCiMjIFJlcGFydGl0aW9uIGFtb25nIGFjY2VwdGVkIHJhbmtzCiMjIyBQaWUgY2hhcnQKCmBgYHtyfQpnZ3Bsb3QoY2V0YWNlYV9wYmRiLCBhZXMoeD1mYWN0b3IocmVjb3JkX3R5cGUpLCBmaWxsPWFjY2VwdGVkX3JhbmspKSArCiAgZ2VvbV9iYXIod2lkdGggPSAxLCBzdGF0ID0gImNvdW50IikgKwogIGNvb3JkX3BvbGFyKCJ5IikgKyAKICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWU9IkFjY2VwdGVkIHJhbmsiKSArCiAgbGFicyh4ID0gTlVMTCwgeSA9IE5VTEwsIGZpbGwgPSBOVUxMLCB0aXRsZSA9ICJSZXBhcnRpdGlvbiBvZiBvY2N1cnJlbmNlcyBhbW9uZyBhY2NlcHRlZCByYW5rcyIpCmBgYAoKJFx0byQgSGFsZiBvZiB0aGUgb2NjdXJyZW5jZXMgYXJlIGlkZW50aWZpZWQgYXQgdGhlIGxldmVsIG9mIHRoZSBzZWNpZXMgYW5kIDEvMyBhdCB0aGUgZ2VudXMgb3IgZmFtaWx5LgoKU29tZSBjbGFkZXMgYXJlIHVucmFua2VkIDoKCmBgYHtyfQp0YWJsZShhcy5jaGFyYWN0ZXIoY2V0YWNlYV9wYmRiW2NldGFjZWFfcGJkYiRhY2NlcHRlZF9yYW5rPT0idW5yYW5rZWQgY2xhZGUiLF0kYWNjZXB0ZWRfbmFtZSkpCmBgYAoKIyMjIFRpbWUgcmVwYXJ0aXRpb24gYnkgcmFuawoKYGBge3IgZmlnLmhlaWdodD02fQpnZ3Bsb3QoY2V0YWNlYV9wYmRiW2NldGFjZWFfcGJkYiRhY2NlcHRlZF9yYW5rICVpbiUgYygic3BlY2llcyIsICJnZW51cyIpLF0sIGFlcyh4PS1hZ2VfcnVuaWYsIGZpbGw9YWNjZXB0ZWRfcmFuaykpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuMSkgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIlRpbWUgKE15KSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobmFtZSA9ICJOdW1iZXIgb2Ygb2NjdXJyZW5jZXMiKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSJBY2NlcHRlZCByYW5rIikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIGdndGl0bGUoIkV2b2x1dGlvbiBvZiB0aGUgbnVtYmVyIG9jY3VycmVuY2VzIHRocm91Z2ggdGltZSAoMC4xIE15IHRpbWUgYmlucyksIGJ5IGFjY2VwdGVkIHJhbmsiKSArCiAgZmFjZXRfZ3JpZChhY2NlcHRlZF9yYW5rIH4gLiwgc2NhbGVzPSJmcmVlIikKCiMgQ291bnQgdGhlIG51bWJlciBvZiBvY2N1cnJlbmNlcyB3aXRoIHRoZSBzYW1lIGFjY2VwdGVkIG5hbWUKY2V0YWNlYV9wYmRiJGFjY2VwdGVkX25hbWVfY291bnQgPC0gc2FwcGx5KGNldGFjZWFfcGJkYiRhY2NlcHRlZF9uYW1lLCBmdW5jdGlvbih4KXt0YWJsZShjZXRhY2VhX3BiZGIkYWNjZXB0ZWRfbmFtZSlbeF19KQojIEdldCB0aGUgZHVyYXRpb24gb2YgdGhlIHRpbWUgaW50ZXJ2YWxzCmNldGFjZWFfcGJkYiRhZ2VfcmFuZ2UgPC0gY2V0YWNlYV9wYmRiJG1heF9tYS1jZXRhY2VhX3BiZGIkbWluX21hCgpnZ3Bsb3QoY2V0YWNlYV9wYmRiLCBhZXMoeD1hY2NlcHRlZF9uYW1lX2NvdW50L2FnZV9yYW5nZSwgZmlsbD1mYWN0b3IobWF4X21hKSkpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aD0wLjEpICsKICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnM9ImxvZzEwIiwgbmFtZT0iRGVuc2l0eSBvZiBvY2N1cnJlbmNlcyAobnVtYmVyL015KSIpICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWU9Ik1heGltdW0gYWdlIChNeSkiKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpKSArCiAgZ2d0aXRsZSgiRGlzdHJpYnV0aW9ucyBvY2N1cnJlbmNlIGRlbnNpdHksIGJ5IGFjY2VwdGVkIHJhbmsiKSArCiAgZmFjZXRfZ3JpZChhY2NlcHRlZF9yYW5rIH4gLikKCmdncGxvdChjZXRhY2VhX3BiZGIsIGFlcyh4PWFjY2VwdGVkX25hbWVfY291bnQvYWdlX3JhbmdlLCBmaWxsPWZhY3Rvcihyb3VuZChhZ2VfcmFuZ2UsIDIpKSkpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aD0wLjEpICsKICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnM9ImxvZzEwIiwgbmFtZT0iRGVuc2l0eSBvZiBvY2N1cnJlbmNlcyAobnVtYmVyL015KSIpICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWU9IkFnZSByYW5nZSAoTXkpIikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIGdndGl0bGUoIkRpc3RyaWJ1dGlvbnMgb2NjdXJyZW5jZSBkZW5zaXR5LCBieSBhY2NlcHRlZCByYW5rIikgKwogIGZhY2V0X2dyaWQoYWNjZXB0ZWRfcmFuayB+IC4pCmBgYAoKJFx0byQgQXBwYXJlbnQgaHVnZSBjbHVzdGVyIG9mIG9jY3VycmVuY2VzIGluIHJlY2VudCB0aW1lcywgd2l0aCB2ZXJ5IHByZWNpc2UgZGF0aW5nID0gQXJ0ZWZhY3QgZHVlIHRvIHRoZSAiUHVsbCBvZiB0aGUgUmVjZW50IiBlZmZlY3QgPyAkXHRvJCBXZSBkZWNpZGVkIHRvICoqcmVtb3ZlIGFsbCBMYXRlIFBsZWlzdG9jZW5lIGFuZCBIb2xvY2VuZSBvY2N1cnJlbmNlcyoqICh0aHVzIHNldHRpbmcgdGhlICRcb21lZ2EkLXNhbXBsaW5nIHRvIDApIGluIG9yZGVyIHRvIGF2b2lkIHRoaXMgYmlhcy4KCmBgYHtyfQpDZXRhY2VhX29jYyA8LSBjZXRhY2VhX3BiZGJbY2V0YWNlYV9wYmRiJGFnZV9ydW5pZiA+IDAuMTI2LF0KCmRhdGEuZnJhbWUoY2V0YWNlYV9wYmRiID0gZGltKGNldGFjZWFfcGJkYilbMV0sCiAgICAgICAgICAgQ2V0YWNlYV9vY2MgPSBkaW0oQ2V0YWNlYV9vY2MpWzFdLAogICAgICAgICAgIHJlbW92ZWQgPSBkaW0oY2V0YWNlYV9wYmRiKVsxXS1kaW0oQ2V0YWNlYV9vY2MpWzFdLAogICAgICAgICAgIHJvdy5uYW1lcyA9ICJOdW1iZXIgb2Ygb2NjdXJyZW5jZXMiKQpgYGAKCmBgYHtyIGZpZy5oZWlnaHQ9Nn0KZ2dwbG90KENldGFjZWFfb2NjWyFDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rICVpbiUgYygic3Vic3BlY2llcyIsICJpbmZyYW9yZGVyIiksXSwgYWVzKHg9LWFnZV9ydW5pZiwgZmlsbD1hY2NlcHRlZF9yYW5rKSkgKwogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMC41KSArCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiVGltZSAoTXkpIikgKwogIHNjYWxlX3lfY29udGludW91cyhuYW1lID0gIk51bWJlciBvZiBvY2N1cnJlbmNlcyIpICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWU9IkFjY2VwdGVkIHJhbmsiKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpKSArCiAgZ2d0aXRsZSgiRXZvbHV0aW9uIG9mIHRoZSBudW1iZXIgb2NjdXJyZW5jZXMgdGhyb3VnaCB0aW1lICgwLjUgTXkgdGltZSBiaW5zKSwgYnkgYWNjZXB0ZWQgcmFuayIpICsKICBmYWNldF9ncmlkKGFjY2VwdGVkX3JhbmsgfiAuLCBzY2FsZXM9ImZyZWUiKQpgYGAKCiRcdG8kIFdlIG9ic2VydmUgc2ltaWxhciB0cmVuZHMgYXQgZWFjaCByYW5rLCB3aXRoIHBlYWtzIGF0IH4xNU15IGFuZCB+NU15LgoKIyMjIFJlZHVuZGFuY3kgb2Ygb2NjdXJyZW5jZXMgd2l0aCB0aGUgc2FtZSBhY2NlcHRlZCBuYW1lCgpgYGB7ciBmaWcuaGVpZ2h0PTZ9CmdncGxvdChjZXRhY2VhX3BiZGIsIGFlcyh4PXJlb3JkZXIoYWNjZXB0ZWRfbmFtZSwgdGFibGUoYWNjZXB0ZWRfbmFtZSlbYWNjZXB0ZWRfbmFtZV0pLCBmaWxsPWFjY2VwdGVkX3JhbmspKSArCiAgZ2VvbV9iYXIoc3RhdD0iY291bnQiKSArIAogIHNjYWxlX3hfZGlzY3JldGUobmFtZSA9ICJBY2NlcHRlZCBuYW1lcyIpICsKICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiLCBuYW1lID0gIk51bWJlciBvZiBjb3JyZXNwb25kaW5nIG9jY3VycmVuY2VzIChsb2ctc2NhbGUpIikgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iQWNjZXB0ZWQgcmFuayIpICsKICB0aGVtZShheGlzLnRleHQueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcy54PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJib3R0b20iKSArCiAgZ2d0aXRsZSgiRGlzdHJpYnV0aW9ucyBvZiB0aGUgbnVtYmVyIG9mIG9jY3VycmVuY2VzIHdpdGggdGhlIHNhbWUgYWNjZXB0ZWQgbmFtZSwgYnkgYWNjZXB0ZWQgcmFuayIpICsKICBmYWNldF9ncmlkKC4gfiBhY2NlcHRlZF9yYW5rLCBzY2FsZXM9ImZyZWVfeCIpCmBgYAoKJFx0byQgfkhhbGYgb2Ygc3BlY2llcy9nZW5lcmEvc3ViZmFtaWxpZXMgaGF2ZSBvbmx5IG9uZSBzcGVjaW1lbiBieSBhY2NlcHRlZCBuYW1lLCBidXQgaXQgY291bGQgZ28gdXAgdG8gfjUwIHdpdGhpbiB0aGUgc2FtZSBzcGVjaWVzIGFuZCB+MjAwIG9jY3VycmVuY2VzIHdpdGhpbiB0aGUgc2FtZSBzdWJvcmRlci4gKipUaG9zZSBkaWZmZXJlbmNlcyB3aWxsIGhhdmUgdG8gYmUgY29ycmVjdGVkIGJlY2F1c2UgaW4gb3VyIG1vZGVsIGFsbCBzcGVjaWVzIGFyZSB1cHBvc2VkIHRvIGhhdmUgdGhlIHNhbWUgYWJ1bmRhbmNlIChpZGVudGljYWwgc2FtcGxpbmcgcmF0ZXMgYW1vbmcgYnJhbmNoZXMpLioqCgokXGltcGxpZXMkIE91ciBnb2FsIG5vdyB3aWxsIGJlIHRvIGNvcnJlY3QgdGhpcyBhYnVuZGFuY2UgYmlhcy4KCiMjIFRpbWUgaW50ZXJ2YWxzID0gc3RyYXRpZ3JhcGhpYyBhZ2UgdW5jZXJ0YWludHkKIyMjIE1pbmltdW0gYW5kIG1heGltdW0gc3RyYXRpZ3JhcGhpYyBsaW1pdHMKCmBgYHtyIGZpZy5oZWlnaHQ9NH0KZ2dwbG90KGNldGFjZWFfcGJkYiwgYWVzKHg9cmVvcmRlcihsYXRlX2ludGVydmFsLCAtbWF4X21hLCBtZWRpYW4pLCBncm91cCA9IC1tYXhfbWEsIGZpbGw9LW1heF9tYSkpICsKICBnZW9tX2JhcihzdGF0PSJjb3VudCIpICsgCiAgc2NhbGVfeF9kaXNjcmV0ZShuYW1lID0gIkxhdGUgU3RyYXRpZ3JhcGhpYyBMaW1pdCIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobmFtZSA9ICJOdW1iZXIgb2YgY29ycmVzcG9uZGluZyBvY2N1cnJlbmNlcyIpICsKICBzY2FsZV9maWxsX2NvbnRpbnVvdXMobmFtZSA9ICJNYXhpbXVtIEFnZSAoTXkpIikgKwogIGdndGl0bGUoIkRpc3RyaWJ1dGlvbiBvZiBtYXhpbXVtIHN0cmF0aWdyYXBoaWMgYWdlcyIpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSkpCgpnZ3Bsb3QoY2V0YWNlYV9wYmRiLCBhZXMoeD1yZW9yZGVyKGVhcmx5X2ludGVydmFsLCAtbWluX21hLCBtZWRpYW4pLCBncm91cCA9IC1taW5fbWEsIGZpbGw9LW1pbl9tYSkpICsKICBnZW9tX2JhcihzdGF0PSJjb3VudCIpICsgCiAgc2NhbGVfeF9kaXNjcmV0ZShuYW1lID0gIkVhcmx5IFN0cmF0aWdyYXBoaWMgTGltaXQiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKG5hbWUgPSAiTnVtYmVyIG9mIGNvcnJlc3BvbmRpbmcgb2NjdXJyZW5jZXMiKSArCiAgc2NhbGVfZmlsbF9jb250aW51b3VzKG5hbWUgPSAiTWluaW11bSBBZ2UgKE15KSIpICsKICBnZ3RpdGxlKCJEaXN0cmlidXRpb24gb2YgbWluaW11bSBzdHJhdGlncmFwaGljIGFnZXMiKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIiwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpKQpgYGAKCiRcdG8kIE1vc3Qgc3BlY2llcyBoYXZlIGEgZWFybHkgYnV0IG5vdCBhIGxhdGUgc3RyYXRpZ3JhcGhpYyBsaW1pdC4KCiMjIyBNaW5pbXVtIGFuZCBtYXhpbXVtIGFnZXMKCmBgYHtyIH0KIyBHZXQgdGhlIHN0cmF0aWdyYXBoaWMgaW50ZXJ2YWwgb2YgdGltZSB1bmNlcnRhaW50eQpDZXRhY2VhX29jYyRhZ2VfaW50ZXJ2YWwgPC0gbWFwcGx5KGZ1bmN0aW9uKG1pbl9hZ2UsIG1heF9hZ2Upe3Bhc3RlKCJbIiwtbWF4X2FnZSwiLCAiLC1taW5fYWdlLCJdIiwgc2VwID0gIiIpfSwgQ2V0YWNlYV9vY2MkbWluX21hLCBDZXRhY2VhX29jYyRtYXhfbWEpCgpnZ3Bsb3QoQ2V0YWNlYV9vY2MsIGFlcyh4PS1tYXhfbWEsIHk9YWdlX2ludGVydmFsKSkgKwogIGdlb21fc2VnbWVudChhZXMoeCA9IC1tYXhfbWEsIHkgPSByZW9yZGVyKGFnZV9pbnRlcnZhbCwgLWFnZV9tZWFuKSwgeGVuZCA9IC1taW5fbWEsIHllbmQ9cmVvcmRlcihhZ2VfaW50ZXJ2YWwsIC1hZ2VfbWVhbiksIGNvbG9yPS1hZ2VfbWVhbikpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJUaW1lIChNeSkiKSArCiAgc2NhbGVfeV9kaXNjcmV0ZShuYW1lID0gIkFnZSBpbnRlcnZhbHMiKSArCiAgbGFicyhjb2xvdXI9Ik1lYW4gYWdlIikgKwogIGdndGl0bGUoIkRpc3RyaWJ1dGlvbiBvZiBhZ2UgaW50ZXJ2YWxzIikgKwogIHRoZW1lKGF4aXMudGV4dC55PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzLnk9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSkKYGBgCgojIyBUaW1lIHJhbmdlcyA9IGR1cmF0aW9uIG9mIHRoZSB0aW1lIGludGVydmFscwojIyMgQ291bnQgb2NjdXJyZW5jZXMgYnkgYWNjZXB0ZWQgbmFtZQoKYGBge3IgZmlnLmhlaWdodD04fQojIENvdW50IHRoZSBudW1iZXIgb2Ygb2NjdXJyZW5jZXMgd2l0aCB0aGUgc2FtZSBhY2NlcHRlZCBuYW1lCkNldGFjZWFfb2NjJGFjY2VwdGVkX25hbWVfY291bnQgPC0gc2FwcGx5KENldGFjZWFfb2NjJGFjY2VwdGVkX25hbWUsIGZ1bmN0aW9uKHgpe3RhYmxlKENldGFjZWFfb2NjJGFjY2VwdGVkX25hbWUpW3hdfSkKCm15X2JyZWFrcyA8LSBjKDEsMywxMCwzNSwxMDAsbWF4KENldGFjZWFfb2NjJGFjY2VwdGVkX25hbWVfY291bnQpKQoKZ2dwbG90KENldGFjZWFfb2NjWyEoQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayAlaW4lIGMoInNwZWNpZXMiLCAiZ2VudXMiLCAiZmFtaWx5IikpLF0sIGFlcyh4PS1tYXhfbWEsIHk9YWNjZXB0ZWRfbmFtZSkpICsKICBnZW9tX3NlZ21lbnQoYWVzKHggPSAtbWF4X21hLCB5ID0gcmVvcmRlcihhY2NlcHRlZF9uYW1lLCAtYWdlX21lYW4pLCB4ZW5kID0gLW1pbl9tYSwgeWVuZD1yZW9yZGVyKGFjY2VwdGVkX25hbWUsIC1hZ2VfbWVhbiksIGNvbG9yPWFjY2VwdGVkX25hbWVfY291bnQpLCBhcnJvdz1hcnJvdyhlbmRzID0gImJvdGgiLCBhbmdsZT05MCwgbGVuZ3RoID0gdW5pdCgxLCAibW0iKSksIGFscGhhPTAuNSkgKwogIGdlb21fcG9pbnQoYWVzKHg9LWFnZV9ydW5pZiksIGNvbD0icmVkIiwgY2V4PTEsIGFscGhhPTAuMykgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIlRpbWUgKE15KSIpICsKICBzY2FsZV95X2Rpc2NyZXRlKG5hbWUgPSAiQWNjZXB0ZWQgcmFua3MiKSArCiAgbGFicyhjb2xvdXI9IkFjY2VwdGVkIG5hbWVzIGNvdW50IikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIHNjYWxlX2NvbG9yX2dyYWRpZW50bihjb2xvdXJzID0gYygiZGFya2JsdWUiLCAiZm9yZXN0Z3JlZW4iLCAiYmxhY2siKSwgdHJhbnM9ImxvZyIsIGJyZWFrcz1teV9icmVha3MsIGxhYmVscz1teV9icmVha3MpICsgCiAgZ2d0aXRsZSgiRGlzdHJpYnV0aW9ucyBvZiBmb3NzaWwgYWdlIHJhbmdlcywgYnkgYWNjZXB0ZWQgcmFuayIpICsKICBmYWNldF9ncmlkKGFjY2VwdGVkX3JhbmsgfiAuLCBzY2FsZXMgPSAiZnJlZSIpCgpnZ3Bsb3QoQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayA9PSJzcGVjaWVzIixdLCBhZXMoeD0tbWF4X21hLCB5PWFjY2VwdGVkX25hbWUpKSArCiAgZ2VvbV9zZWdtZW50KGFlcyh4ID0gLW1heF9tYSwgeSA9IHJlb3JkZXIoYWNjZXB0ZWRfbmFtZSwgLWFnZV9tZWFuKSwgeGVuZCA9IC1taW5fbWEsIHllbmQ9cmVvcmRlcihhY2NlcHRlZF9uYW1lLCAtYWdlX21lYW4pLCBjb2xvcj1hY2NlcHRlZF9uYW1lX2NvdW50KSwgYXJyb3c9YXJyb3coZW5kcyA9ICJib3RoIiwgYW5nbGU9OTAsIGxlbmd0aCA9IHVuaXQoMSwgIm1tIikpLCBhbHBoYT0wLjUpICsKICBnZW9tX3BvaW50KGFlcyh4PS1hZ2VfcnVuaWYpLCBjb2w9InJlZCIsIGNleD0xLCBhbHBoYT0wLjMpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJUaW1lIChNeSkiKSArCiAgc2NhbGVfeV9kaXNjcmV0ZShuYW1lID0gIkFnZSByYW5nZXMiKSArCiAgbGFicyhjb2xvdXI9IkFjY2VwdGVkIG5hbWVzIGNvdW50IikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT0yKSkgKwogIHNjYWxlX2NvbG9yX2dyYWRpZW50bihjb2xvdXJzID0gYygiZGFya2JsdWUiLCAiZm9yZXN0Z3JlZW4iLCAiYmxhY2siKSwgdHJhbnM9ImxvZyIsIGJyZWFrcz1teV9icmVha3MsIGxhYmVscz1teV9icmVha3MpICsgCiAgZ2d0aXRsZSgiRGlzdHJpYnV0aW9ucyBvZiBmb3NzaWwgYWdlIHJhbmdlcyAoc3BlY2llcykiKSArCiAgZmFjZXRfZ3JpZChhY2NlcHRlZF9yYW5rIH4gLiwgc2NhbGVzID0gImZyZWUiKQoKZ2dwbG90KENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGFjY2VwdGVkX3JhbmsgPT0iZ2VudXMiLF0sIGFlcyh4PS1tYXhfbWEsIHk9YWNjZXB0ZWRfbmFtZSkpICsKICBnZW9tX3NlZ21lbnQoYWVzKHggPSAtbWF4X21hLCB5ID0gcmVvcmRlcihhY2NlcHRlZF9uYW1lLCAtYWdlX21lYW4pLCB4ZW5kID0gLW1pbl9tYSwgeWVuZD1yZW9yZGVyKGFjY2VwdGVkX25hbWUsIC1hZ2VfbWVhbiksIGNvbG9yPWFjY2VwdGVkX25hbWVfY291bnQpLCBhcnJvdz1hcnJvdyhlbmRzID0gImJvdGgiLCBhbmdsZT05MCwgbGVuZ3RoID0gdW5pdCgxLCAibW0iKSksIGFscGhhPTAuNSkgKwogIGdlb21fcG9pbnQoYWVzKHg9LWFnZV9ydW5pZiksIGNvbD0icmVkIiwgY2V4PTEsIGFscGhhPTAuMykgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIlRpbWUgKE15KSIpICsKICBzY2FsZV95X2Rpc2NyZXRlKG5hbWUgPSAiR2VudXMiKSArCiAgbGFicyhjb2xvdXI9IkFjY2VwdGVkIG5hbWVzIGNvdW50IikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT02KSkgKwogIHNjYWxlX2NvbG9yX2dyYWRpZW50bihjb2xvdXJzID0gYygiZGFya2JsdWUiLCAiZm9yZXN0Z3JlZW4iLCAiYmxhY2siKSwgdHJhbnM9ImxvZyIsIGJyZWFrcz1teV9icmVha3MsIGxhYmVscz1teV9icmVha3MpICsgCiAgZ2d0aXRsZSgiRGlzdHJpYnV0aW9ucyBvZiBmb3NzaWwgYWdlIHJhbmdlcyAoZ2VuZXJhKSIpICsKICBmYWNldF9ncmlkKGFjY2VwdGVkX3JhbmsgfiAuLCBzY2FsZXMgPSAiZnJlZSIpCgpnZ3Bsb3QoQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayA9PSJmYW1pbHkiLF0sIGFlcyh4PS1tYXhfbWEsIHk9YWNjZXB0ZWRfbmFtZSkpICsKICBnZW9tX3NlZ21lbnQoYWVzKHggPSAtbWF4X21hLCB5ID0gcmVvcmRlcihhY2NlcHRlZF9uYW1lLCAtYWdlX21lYW4pLCB4ZW5kID0gLW1pbl9tYSwgeWVuZD1yZW9yZGVyKGFjY2VwdGVkX25hbWUsIC1hZ2VfbWVhbiksIGNvbG9yPWFjY2VwdGVkX25hbWVfY291bnQpLCBhcnJvdz1hcnJvdyhlbmRzID0gImJvdGgiLCBhbmdsZT05MCwgbGVuZ3RoID0gdW5pdCgxLCAibW0iKSksIGFscGhhPTAuNSkgKwogIGdlb21fcG9pbnQoYWVzKHg9LWFnZV9ydW5pZiksIGNvbD0icmVkIiwgY2V4PTEsIGFscGhhPTAuMykgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIlRpbWUgKE15KSIpICsKICBzY2FsZV95X2Rpc2NyZXRlKG5hbWUgPSAiR2VudXMiKSArCiAgbGFicyhjb2xvdXI9IkFjY2VwdGVkIG5hbWVzIGNvdW50IikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIHNjYWxlX2NvbG9yX2dyYWRpZW50bihjb2xvdXJzID0gYygiZGFya2JsdWUiLCAiZm9yZXN0Z3JlZW4iLCAiYmxhY2siKSwgdHJhbnM9ImxvZyIsIGJyZWFrcz1teV9icmVha3MsIGxhYmVscz1teV9icmVha3MpICsgCiAgZ2d0aXRsZSgiRGlzdHJpYnV0aW9ucyBvZiBmb3NzaWwgYWdlIHJhbmdlcyAoZmFtaWxpZXMpIikgKwogIGZhY2V0X2dyaWQoYWNjZXB0ZWRfcmFuayB+IC4sIHNjYWxlcyA9ICJmcmVlIikKYGBgCgokXHRvJCBTb21lIG9jY3VycmVuY2VzIGhhdmUgdG9vIG11Y2ggYWdlIHVuY2VydGFpbnR5LCB0aGV5IHJpc2sgdG8gYXJ0aWZpY2lhbGx5IGluY3JlYXNlIHNwZWNpZXMgZHVyYXRpb25zLgoKIyMjIFJlbW92ZSBvY2N1cnJlbmNlcyB3aXRoIGhpZ2hseSB1bmNlcnRhaW4gZGF0aW5nIChyYW5nZSA+IDEwTXkpCgpgYGB7cn0KIyBHZXQgdGhlIGR1cmF0aW9uIG9mIHRoZSB0aW1lIGludGVydmFscwpDZXRhY2VhX29jYyRhZ2VfcmFuZ2UgPC0gQ2V0YWNlYV9vY2MkbWF4X21hLUNldGFjZWFfb2NjJG1pbl9tYQojIE9jY3VycmVuY2VzIHdob3NlIHRpbWUgcmFuZ2UgaXMgbG93ZXIgdGhhbiA4IG1pbGxpb24geWVhcnMKZGltKENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGFnZV9yYW5nZTwxMCxdKQoKZ2dwbG90KENldGFjZWFfb2NjLCBhZXMoeD1hZ2VfcmFuZ2UsIGZpbGw9YWNjZXB0ZWRfcmFuaykpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDEpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJBZ2UgdW5jZXJ0YWludHkgcmFuZ2UgKE15KSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobmFtZSA9ICJOdW1iZXIgb2YgY29ycmVzcG9uZGluZyBvY2N1cnJlbmNlcyIpICsKICBnZW9tX3NlZ21lbnQoYWVzKHggPSA5LjUsIHkgPSAwLCB4ZW5kID0gOS41LCB5ZW5kPTEwNTApLCBjb2xvcj0iYmxhY2siLCBsaW5ldHlwZT0iZGFzaGVkIikgKwogIGdndGl0bGUoIkRpc3RyaWJ1dGlvbiBvZiBvY2N1cnJlbmNlcycgYWdlIHVuY2VydGFpbnR5IHJhbmdlIikKYGBgCgpNb3N0IG9mIG9jY3VycmVuY2VzIHNob3cgbGVzcyB0aGFuIDEwIE15IGFnZSB1bmNlcnRhaW50eSwgbGV0J3MgdHJ5IHRvIGtlZXAgb25seSB0aGVzZSBvbmVzLgoKYGBge3J9CmRhdGEuZnJhbWUoYWxsX3JhbmdlcyA9IGRpbShDZXRhY2VhX29jYylbMV0sCiAgICAgICAgICAgc21hbGxlcl8xME15ID0gZGltKENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGFnZV9yYW5nZTwxMCxdKVsxXSwKICAgICAgICAgICByZW1vdmVkID0gZGltKENldGFjZWFfb2NjKVsxXS1kaW0oQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWdlX3JhbmdlPDEwLF0pWzFdLCByb3cubmFtZXMgPSAiTnVtYmVyIG9mIG9jY3VycmVuY2VzIikKYGBgCgpgYGB7ciBmaWcuaGVpZ2h0PTZ9CmdncGxvdChDZXRhY2VhX29jYywgYWVzKHg9YWdlX3J1bmlmLCB5PWFnZV9yYW5nZSkpICsKICBnZW9tX3BvaW50KGFscGhhPTAuMDUpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJVbmlmb3JtbHkgZHJhd24gYWdlIChNeSkiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKG5hbWUgPSAiQWdlIHVuY2VydGFpbnR5IHJhbmdlIChNeSkiKSArCiAgZ2d0aXRsZSgiRGlzdHJpYnV0aW9uIG9mIG9jY3VycmVuY2VzJyBhZ2UgdW5jZXJ0YWludHkgcmFuZ2UiKQoKZ2dwbG90KENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGFnZV9yYW5nZSAhPSA2My40MTIsXSwgYWVzKHg9YWdlX3J1bmlmLCB5PWFnZV9yYW5nZSkpICsKICBnZW9tX3BvaW50KGFscGhhPTAuMDUpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJVbmlmb3JtbHkgZHJhd24gYWdlIChNeSkiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKG5hbWUgPSAiQWdlIHVuY2VydGFpbnR5IHJhbmdlIChNeSkiKSArCiAgZ2VvbV9zZWdtZW50KGFlcyh4ID0gMCwgeSA9IDEwLCB4ZW5kPTYwLCB5ZW5kID0gMTApLCBjb2xvcj0iYmxhY2siLCBsaW5ldHlwZT0iZGFzaGVkIikgKwogIGdndGl0bGUoIkRpc3RyaWJ1dGlvbiBvZiBvY2N1cnJlbmNlcycgYWdlIHVuY2VydGFpbnR5IHJhbmdlIikKCmdncGxvdChDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhZ2VfcmFuZ2U8MTAsXSwgYWVzKHg9YWdlX3J1bmlmLCB5PWFnZV9yYW5nZSkpICsKICBnZW9tX3BvaW50KGFscGhhPTAuMDUpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJVbmlmb3JtbHkgZHJhd24gYWdlIChNeSkiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKG5hbWUgPSAiQWdlIHVuY2VydGFpbnR5IHJhbmdlIChNeSkiKSArCiAgZ2d0aXRsZSgiRGlzdHJpYnV0aW9uIG9mIG9jY3VycmVuY2VzJyBhZ2UgdW5jZXJ0YWludHkgcmFuZ2UiKQoKaGlzdCgtQ2V0YWNlYV9vY2MkYWdlX3J1bmlmLCBicmVha3MgPSA1MCwgY29sPSJyZWQiLCBwcm9iYWJpbGl0eT1ULCBtYWluPSJEaXN0cmlidXRpb24gb2Ygb2NjdXJyZW5jZXMsIHdpdGggKHJlZCkgb2Ygd2l0aG91dCAoYmx1ZSkgcmVjZW50IHNhbXBsZXMiLCB4bGFiID0gIlRpbWUgKE15KSIsIHlsYWIgPSAiUHJvcG9ydGlvbiBvZiBvY2N1cnJlbmNlcyIpCmhpc3QoLUNldGFjZWFfb2NjW0NldGFjZWFfb2NjJGFnZV9yYW5nZTwxMCxdJGFnZV9ydW5pZiwgYnJlYWtzID0gNTAsIGNvbD0iYmx1ZSIsIHByb2JhYmlsaXR5PVQsIGRlbnNpdHk9VCwgYWRkPVQpCmBgYAoKJFx0byQgVGhlIHJlbW92YWwgb2YgaGlnaGx5IHVuY2VydGFpbiBvY2N1cnJlbmNlcyBzZWVtcyB0byBiZSBvbmx5IGEgbGl0dGxlIGJpYXNlZCwgZXZlbiBpZiB1bmNlcnRhaW50eSBnbG9iYWxseSBpbmNyZWFzZXMgd2l0aCBhZ2UuCgpgYGB7ciBmaWcuaGVpZ2h0PTh9Cm15X2JyZWFrcyA8LSBjKDEsMywxMCwzNSwxMDAsbWF4KENldGFjZWFfb2NjJGFjY2VwdGVkX25hbWVfY291bnQpKQoKZ2dwbG90KENldGFjZWFfb2NjWyEoQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayAlaW4lIGMoInNwZWNpZXMiLCAiZ2VudXMiLCAiZmFtaWx5IikpICYgQ2V0YWNlYV9vY2MkYWdlX3JhbmdlPDEwLF0sIGFlcyh4PS1tYXhfbWEsIHk9YWNjZXB0ZWRfbmFtZSkpICsKICBnZW9tX3NlZ21lbnQoYWVzKHggPSAtbWF4X21hLCB5ID0gcmVvcmRlcihhY2NlcHRlZF9uYW1lLCAtYWdlX21lYW4pLCB4ZW5kID0gLW1pbl9tYSwgeWVuZD1yZW9yZGVyKGFjY2VwdGVkX25hbWUsIC1hZ2VfbWVhbiksIGNvbG9yPWFjY2VwdGVkX25hbWVfY291bnQpLCBhcnJvdz1hcnJvdyhlbmRzID0gImJvdGgiLCBhbmdsZT05MCwgbGVuZ3RoID0gdW5pdCgxLCAibW0iKSksIGFscGhhPTAuNSkgKwogIGdlb21fcG9pbnQoYWVzKHg9LWFnZV9ydW5pZiksIGNvbD0icmVkIiwgY2V4PTEsIGFscGhhPTAuNSkgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIlRpbWUgKE15KSIpICsKICBzY2FsZV95X2Rpc2NyZXRlKG5hbWUgPSAiQWNjZXB0ZWQgcmFua3MiKSArCiAgbGFicyhjb2xvdXI9IkFjY2VwdGVkIG5hbWVzIGNvdW50IikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIHNjYWxlX2NvbG9yX2dyYWRpZW50bihjb2xvdXJzID0gYygiZGFya2JsdWUiLCAiZm9yZXN0Z3JlZW4iLCAiYmxhY2siKSwgdHJhbnM9ImxvZyIsIGJyZWFrcz1teV9icmVha3MsIGxhYmVscz1teV9icmVha3MpICsgCiAgZ2d0aXRsZSgiRGlzdHJpYnV0aW9ucyBvZiBmb3NzaWwgYWdlIHJhbmdlcywgYnkgYWNjZXB0ZWQgcmFuayIpICsKICBmYWNldF9ncmlkKGFjY2VwdGVkX3JhbmsgfiAuLCBzY2FsZXMgPSAiZnJlZSIpCgpnZ3Bsb3QoQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayA9PSJzcGVjaWVzIiAmIENldGFjZWFfb2NjJGFnZV9yYW5nZTwxMCxdLCBhZXMoeD0tbWF4X21hLCB5PWFjY2VwdGVkX25hbWUpKSArCiAgZ2VvbV9zZWdtZW50KGFlcyh4ID0gLW1heF9tYSwgeSA9IHJlb3JkZXIoYWNjZXB0ZWRfbmFtZSwgLWFnZV9tZWFuKSwgeGVuZCA9IC1taW5fbWEsIHllbmQ9cmVvcmRlcihhY2NlcHRlZF9uYW1lLCAtYWdlX21lYW4pLCBjb2xvcj1hY2NlcHRlZF9uYW1lX2NvdW50KSwgYXJyb3c9YXJyb3coZW5kcyA9ICJib3RoIiwgYW5nbGU9OTAsIGxlbmd0aCA9IHVuaXQoMSwgIm1tIikpLCBhbHBoYT0wLjUpICsKICBnZW9tX3BvaW50KGFlcyh4PS1hZ2VfcnVuaWYpLCBjb2w9InJlZCIsIGNleD0xLCBhbHBoYT0wLjUpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJUaW1lIChNeSkiKSArCiAgc2NhbGVfeV9kaXNjcmV0ZShuYW1lID0gIkFnZSByYW5nZXMiKSArCiAgbGFicyhjb2xvdXI9IkFjY2VwdGVkIG5hbWVzIGNvdW50IikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT0yKSkgKwogIHNjYWxlX2NvbG9yX2dyYWRpZW50bihjb2xvdXJzID0gYygiZGFya2JsdWUiLCAiZm9yZXN0Z3JlZW4iLCAiYmxhY2siKSwgdHJhbnM9ImxvZyIsIGJyZWFrcz1teV9icmVha3MsIGxhYmVscz1teV9icmVha3MpICsgCiAgZ2d0aXRsZSgiRGlzdHJpYnV0aW9ucyBvZiBmb3NzaWwgYWdlIHJhbmdlcyAoc3BlY2llcykiKSArCiAgZmFjZXRfZ3JpZChhY2NlcHRlZF9yYW5rIH4gLiwgc2NhbGVzID0gImZyZWUiKQoKZ2dwbG90KENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGFjY2VwdGVkX3JhbmsgPT0iZ2VudXMiICYgQ2V0YWNlYV9vY2MkYWdlX3JhbmdlPDEwLF0sIGFlcyh4PS1tYXhfbWEsIHk9YWNjZXB0ZWRfbmFtZSkpICsKICBnZW9tX3NlZ21lbnQoYWVzKHggPSAtbWF4X21hLCB5ID0gcmVvcmRlcihhY2NlcHRlZF9uYW1lLCAtYWdlX21lYW4pLCB4ZW5kID0gLW1pbl9tYSwgeWVuZD1yZW9yZGVyKGFjY2VwdGVkX25hbWUsIC1hZ2VfbWVhbiksIGNvbG9yPWFjY2VwdGVkX25hbWVfY291bnQpLCBhcnJvdz1hcnJvdyhlbmRzID0gImJvdGgiLCBhbmdsZT05MCwgbGVuZ3RoID0gdW5pdCgxLCAibW0iKSksIGFscGhhPTAuNSkgKwogIGdlb21fcG9pbnQoYWVzKHg9LWFnZV9ydW5pZiksIGNvbD0icmVkIiwgY2V4PTEsIGFscGhhPTAuNSkgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIlRpbWUgKE15KSIpICsKICBzY2FsZV95X2Rpc2NyZXRlKG5hbWUgPSAiR2VudXMiKSArCiAgbGFicyhjb2xvdXI9IkFjY2VwdGVkIG5hbWVzIGNvdW50IikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT02KSkgKwogIHNjYWxlX2NvbG9yX2dyYWRpZW50bihjb2xvdXJzID0gYygiZGFya2JsdWUiLCAiZm9yZXN0Z3JlZW4iLCAiYmxhY2siKSwgdHJhbnM9ImxvZyIsIGJyZWFrcz1teV9icmVha3MsIGxhYmVscz1teV9icmVha3MpICsgCiAgZ2d0aXRsZSgiRGlzdHJpYnV0aW9ucyBvZiBmb3NzaWwgYWdlIHJhbmdlcyAoZ2VuZXJhKSIpICsKICBmYWNldF9ncmlkKGFjY2VwdGVkX3JhbmsgfiAuLCBzY2FsZXMgPSAiZnJlZSIpCgpnZ3Bsb3QoQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayA9PSJmYW1pbHkiICYgQ2V0YWNlYV9vY2MkYWdlX3JhbmdlPDEwLF0sIGFlcyh4PS1tYXhfbWEsIHk9YWNjZXB0ZWRfbmFtZSkpICsKICBnZW9tX3NlZ21lbnQoYWVzKHggPSAtbWF4X21hLCB5ID0gcmVvcmRlcihhY2NlcHRlZF9uYW1lLCAtYWdlX21lYW4pLCB4ZW5kID0gLW1pbl9tYSwgeWVuZD1yZW9yZGVyKGFjY2VwdGVkX25hbWUsIC1hZ2VfbWVhbiksIGNvbG9yPWFjY2VwdGVkX25hbWVfY291bnQpLCBhcnJvdz1hcnJvdyhlbmRzID0gImJvdGgiLCBhbmdsZT05MCwgbGVuZ3RoID0gdW5pdCgxLCAibW0iKSksIGFscGhhPTAuNSkgKwogIGdlb21fcG9pbnQoYWVzKHg9LWFnZV9ydW5pZiksIGNvbD0icmVkIiwgY2V4PTEsIGFscGhhPTAuNSkgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIlRpbWUgKE15KSIpICsKICBzY2FsZV95X2Rpc2NyZXRlKG5hbWUgPSAiR2VudXMiKSArCiAgbGFicyhjb2xvdXI9IkFjY2VwdGVkIG5hbWVzIGNvdW50IikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIHNjYWxlX2NvbG9yX2dyYWRpZW50bihjb2xvdXJzID0gYygiZGFya2JsdWUiLCAiZm9yZXN0Z3JlZW4iLCAiYmxhY2siKSwgdHJhbnM9ImxvZyIsIGJyZWFrcz1teV9icmVha3MsIGxhYmVscz1teV9icmVha3MpICsgCiAgZ2d0aXRsZSgiRGlzdHJpYnV0aW9ucyBvZiBmb3NzaWwgYWdlIHJhbmdlcyAoZmFtaWxpZXMpIikgKwogIGZhY2V0X2dyaWQoYWNjZXB0ZWRfcmFuayB+IC4sIHNjYWxlcyA9ICJmcmVlIikKYGBgCgokXHRvJCBTb21lIHNwZWNpZXMgKG9yIG90aGVyIHJhbmtzKSBoYXZlIHNldmVyYWwgb2NjdXJyZW5jZXMgd2l0aCBzZXZlcmFsIHRpbWUgcmFuZ2VzLCAqKmxldCdzIGNvbWJpbmUgdGhlbSBpbnRvIGEgdW5pcXVlIHJhbmdlIGNvdmVyaW5nIGFsbCB0aGUgb3RoZXJzKiouCgojIyBDb21iaW5lZCB0aW1lIHJhbmdlcyA9IHVuaXF1ZSB0aW1lIHJhbmdlIGZvciBvY2N1cnJlbmNlcyB3aXRoIHRoZSBzYW1lIG5hbWUgKHdpdGhvdXQgdGhlIGJpZ2dlc3Qgb25lcykKCmBgYHtyIGZpZy5oZWlnaHQ9OCwgd2FybmluZz1GQUxTRX0KIyBHZXQgdGhlIG1pbmltdW4gb2YgdGhlIG1pbmltYWwgYWdlcyBmb3IgZWFjaCBhY2NlcHRlZCBuYW1lCkNldGFjZWFfb2NjJG1pbl9taW5fbWEgPC0gYXBwbHkoQ2V0YWNlYV9vY2MsIDEsIGZ1bmN0aW9uKFgpe21pbihDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9uYW1lPT1YWyJhY2NlcHRlZF9uYW1lIl0gJiBDZXRhY2VhX29jYyRhZ2VfcmFuZ2U8MTAsXSRtaW5fbWEpfSkKIyBHZXQgdGhlIG1heGltdW0gb2YgdGhlIG1heGltYWwgYWdlcyBmb3IgZWFjaCBhY2NlcHRlZCBuYW1lCkNldGFjZWFfb2NjJG1heF9tYXhfbWEgPC0gYXBwbHkoQ2V0YWNlYV9vY2MsIDEsIGZ1bmN0aW9uKFgpe21heChDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9uYW1lPT1YWyJhY2NlcHRlZF9uYW1lIl0gJiBDZXRhY2VhX29jYyRhZ2VfcmFuZ2U8MTAsXSRtYXhfbWEpfSkKIyBHZXQgdGhlIGNvbWJpbmVkIHRpbWUgaW50ZXJ2YWwKQ2V0YWNlYV9vY2MkYWdlX2NvbWJpbmVkX2ludGVydmFsIDwtIG1hcHBseShmdW5jdGlvbihtaW5fbWluX2FnZSwgbWF4X21heF9hZ2Upe3Bhc3RlKCJbIiwtbWF4X21heF9hZ2UsIiwgIiwtbWluX21pbl9hZ2UsIl0iLCBzZXAgPSAiIil9LCBDZXRhY2VhX29jYyRtaW5fbWluX21hLCBDZXRhY2VhX29jYyRtYXhfbWF4X21hKQojIEdldCB0aGUgY29tYmluZWQgdGltZSBpbnRlcnZhbCBtZWFuCkNldGFjZWFfb2NjJGFnZV9jb21iaW5lZF9tZWFuIDwtIChDZXRhY2VhX29jYyRtaW5fbWluX21hICsgQ2V0YWNlYV9vY2MkbWF4X21heF9tYSkvMgojIEdldCB0aGUgZHVyYXRpb24gb2YgdGhlIGNvbWJpbmVkIHRpbWUgaW50ZXJ2YWxzCkNldGFjZWFfb2NjJGFnZV9jb21iaW5lZF9yYW5nZSA8LSBDZXRhY2VhX29jYyRtYXhfbWF4X21hLUNldGFjZWFfb2NjJG1pbl9taW5fbWEKCmdncGxvdChDZXRhY2VhX29jY1shKENldGFjZWFfb2NjJGFjY2VwdGVkX3JhbmsgJWluJSBjKCJzcGVjaWVzIiwgImdlbnVzIiwgImZhbWlseSIpKSAmIENldGFjZWFfb2NjJGFnZV9yYW5nZTwxMCxdLCBhZXMoeD0tbWF4X21hLCB5PWFjY2VwdGVkX25hbWUpKSArCiAgZ2VvbV9zZWdtZW50KGFlcyh4ID0gLW1heF9tYXhfbWEsIHkgPSByZW9yZGVyKGFjY2VwdGVkX25hbWUsIC1hZ2VfY29tYmluZWRfbWVhbiksIHhlbmQgPSAtbWluX21pbl9tYSwgeWVuZD1yZW9yZGVyKGFjY2VwdGVkX25hbWUsIC1hZ2VfY29tYmluZWRfbWVhbiksIGNvbG9yPWFjY2VwdGVkX25hbWVfY291bnQpLCBhcnJvdz1hcnJvdyhlbmRzID0gImJvdGgiLCBhbmdsZT05MCwgbGVuZ3RoID0gdW5pdCgxLCAibW0iKSksIGFscGhhPTAuNSkgKwogIGdlb21fcG9pbnQoYWVzKHg9LWFnZV9ydW5pZiksIGNvbD0icmVkIiwgY2V4PTEsIGFscGhhPTAuNSkgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIlRpbWUgKE15KSIpICsKICBzY2FsZV95X2Rpc2NyZXRlKG5hbWUgPSAiQWNjZXB0ZWQgcmFua3MiKSArCiAgbGFicyhjb2xvdXI9IkFjY2VwdGVkIG5hbWVzIGNvdW50IikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIHNjYWxlX2NvbG9yX2dyYWRpZW50bihjb2xvdXJzID0gYygiZGFya2JsdWUiLCAiZm9yZXN0Z3JlZW4iLCAiYmxhY2siKSwgdHJhbnM9ImxvZyIsIGJyZWFrcz1teV9icmVha3MsIGxhYmVscz1teV9icmVha3MpICsgCiAgZ2d0aXRsZSgiRGlzdHJpYnV0aW9ucyBvZiBmb3NzaWwgY29tYmluZWQgYWdlIHJhbmdlcywgYnkgYWNjZXB0ZWQgcmFuayIpICsKICBmYWNldF9ncmlkKGFjY2VwdGVkX3JhbmsgfiAuLCBzY2FsZXMgPSAiZnJlZSIpCgpnZ3Bsb3QoQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayA9PSJzcGVjaWVzIiAmIENldGFjZWFfb2NjJGFnZV9yYW5nZTwxMCxdLCBhZXMoeD0tbWF4X21hLCB5PWFjY2VwdGVkX25hbWUpKSArCiAgZ2VvbV9zZWdtZW50KGFlcyh4ID0gLW1heF9tYXhfbWEsIHkgPSByZW9yZGVyKGFjY2VwdGVkX25hbWUsIC1hZ2VfY29tYmluZWRfbWVhbiksIHhlbmQgPSAtbWluX21pbl9tYSwgeWVuZD1yZW9yZGVyKGFjY2VwdGVkX25hbWUsIC1hZ2VfY29tYmluZWRfbWVhbiksIGNvbG9yPWFjY2VwdGVkX25hbWVfY291bnQpLCBhcnJvdz1hcnJvdyhlbmRzID0gImJvdGgiLCBhbmdsZT05MCwgbGVuZ3RoID0gdW5pdCgxLCAibW0iKSksIGFscGhhPTAuNSkgKwogIGdlb21fcG9pbnQoYWVzKHg9LWFnZV9ydW5pZiksIGNvbD0icmVkIiwgY2V4PTEsIGFscGhhPTAuNSkgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIlRpbWUgKE15KSIpICsKICBzY2FsZV95X2Rpc2NyZXRlKG5hbWUgPSAiQWdlIHJhbmdlcyIpICsKICBsYWJzKGNvbG91cj0iQWNjZXB0ZWQgbmFtZXMgY291bnQiKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPTIpKSArCiAgc2NhbGVfY29sb3JfZ3JhZGllbnRuKGNvbG91cnMgPSBjKCJkYXJrYmx1ZSIsICJmb3Jlc3RncmVlbiIsICJibGFjayIpLCB0cmFucz0ibG9nIiwgYnJlYWtzPW15X2JyZWFrcywgbGFiZWxzPW15X2JyZWFrcykgKyAKICBnZ3RpdGxlKCJEaXN0cmlidXRpb25zIG9mIGZvc3NpbCBjb21iaW5lZCBhZ2UgcmFuZ2VzIChzcGVjaWVzKSIpICsKICBmYWNldF9ncmlkKGFjY2VwdGVkX3JhbmsgfiAuLCBzY2FsZXMgPSAiZnJlZSIpCgpnZ3Bsb3QoQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayA9PSJnZW51cyIgJiBDZXRhY2VhX29jYyRhZ2VfcmFuZ2U8MTAsXSwgYWVzKHg9LW1heF9tYSwgeT1hY2NlcHRlZF9uYW1lKSkgKwogIGdlb21fc2VnbWVudChhZXMoeCA9IC1tYXhfbWF4X21hLCB5ID0gcmVvcmRlcihhY2NlcHRlZF9uYW1lLCAtYWdlX2NvbWJpbmVkX21lYW4pLCB4ZW5kID0gLW1pbl9taW5fbWEsIHllbmQ9cmVvcmRlcihhY2NlcHRlZF9uYW1lLCAtYWdlX2NvbWJpbmVkX21lYW4pLCBjb2xvcj1hY2NlcHRlZF9uYW1lX2NvdW50KSwgYXJyb3c9YXJyb3coZW5kcyA9ICJib3RoIiwgYW5nbGU9OTAsIGxlbmd0aCA9IHVuaXQoMSwgIm1tIikpLCBhbHBoYT0wLjUpICsKICBnZW9tX3BvaW50KGFlcyh4PS1hZ2VfcnVuaWYpLCBjb2w9InJlZCIsIGNleD0xLCBhbHBoYT0wLjUpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJUaW1lIChNeSkiKSArCiAgc2NhbGVfeV9kaXNjcmV0ZShuYW1lID0gIkdlbmVyYSIpICsKICBsYWJzKGNvbG91cj0iQWNjZXB0ZWQgbmFtZXMgY291bnQiKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPTYpKSArCiAgc2NhbGVfY29sb3JfZ3JhZGllbnRuKGNvbG91cnMgPSBjKCJkYXJrYmx1ZSIsICJmb3Jlc3RncmVlbiIsICJibGFjayIpLCB0cmFucz0ibG9nIiwgYnJlYWtzPW15X2JyZWFrcywgbGFiZWxzPW15X2JyZWFrcykgKyAKICBnZ3RpdGxlKCJEaXN0cmlidXRpb25zIG9mIGZvc3NpbCBjb21iaW5lZCBhZ2UgcmFuZ2VzIChnZW5lcmEpIikgKwogIGZhY2V0X2dyaWQoYWNjZXB0ZWRfcmFuayB+IC4sIHNjYWxlcyA9ICJmcmVlIikKCmdncGxvdChDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rID09ImZhbWlseSIgJiBDZXRhY2VhX29jYyRhZ2VfcmFuZ2U8MTAsXSwgYWVzKHg9LW1heF9tYSwgeT1hY2NlcHRlZF9uYW1lKSkgKwogIGdlb21fc2VnbWVudChhZXMoeCA9IC1tYXhfbWF4X21hLCB5ID0gcmVvcmRlcihhY2NlcHRlZF9uYW1lLCAtYWdlX2NvbWJpbmVkX21lYW4pLCB4ZW5kID0gLW1pbl9taW5fbWEsIHllbmQ9cmVvcmRlcihhY2NlcHRlZF9uYW1lLCAtYWdlX2NvbWJpbmVkX21lYW4pLCBjb2xvcj1hY2NlcHRlZF9uYW1lX2NvdW50KSwgYXJyb3c9YXJyb3coZW5kcyA9ICJib3RoIiwgYW5nbGU9OTAsIGxlbmd0aCA9IHVuaXQoMSwgIm1tIikpLCBhbHBoYT0wLjUpICsKICBnZW9tX3BvaW50KGFlcyh4PS1hZ2VfcnVuaWYpLCBjb2w9InJlZCIsIGNleD0xLCBhbHBoYT0wLjUpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJUaW1lIChNeSkiKSArCiAgc2NhbGVfeV9kaXNjcmV0ZShuYW1lID0gIkZhbWlsaWVzIikgKwogIGxhYnMoY29sb3VyPSJBY2NlcHRlZCBuYW1lcyBjb3VudCIpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCkpICsKICBzY2FsZV9jb2xvcl9ncmFkaWVudG4oY29sb3VycyA9IGMoImRhcmtibHVlIiwgImZvcmVzdGdyZWVuIiwgImJsYWNrIiksIHRyYW5zPSJsb2ciLCBicmVha3M9bXlfYnJlYWtzLCBsYWJlbHM9bXlfYnJlYWtzKSArIAogIGdndGl0bGUoIkRpc3RyaWJ1dGlvbnMgb2YgZm9zc2lsIGNvbWJpbmVkIGFnZSByYW5nZXMgKGZhbWlsaWVzKSIpICsKICBmYWNldF9ncmlkKGFjY2VwdGVkX3JhbmsgfiAuLCBzY2FsZXMgPSAiZnJlZSIpCmBgYAoKIyMgT2NjdXJyZW5jZSBkZW5zaXR5CiMjIyBEZW5zaXR5IGRpc3RyaWJ1dGlvbnMKCmBgYHtyIGZpZy5oZWlnaHQ9Nn0KIyBHZXQgaW50ZXJ2YWwgZGVuc2l0eSBvZiBvY2N1cnJlbmNlcwpDZXRhY2VhX29jYyRvY2N1cnJlbmNlX2RlbnNpdHkgPC0gQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfbmFtZV9jb3VudC9DZXRhY2VhX29jYyRhZ2VfcmFuZ2UKCmdncGxvdChDZXRhY2VhX29jY1shKENldGFjZWFfb2NjJGFjY2VwdGVkX3JhbmsgJWluJSBjKCJzdWJzcGVjaWVzIiwgImluZnJhb3JkZXIiKSkgJiBDZXRhY2VhX29jYyRhZ2VfcmFuZ2U8MTAsXSwgYWVzKHg9b2NjdXJyZW5jZV9kZW5zaXR5LCBmaWxsPWZhY3RvcihhY2NlcHRlZF9uYW1lX2NvdW50KSkpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aD0wLjEpICsKICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnM9ImxvZzEwIiwgbmFtZT0iRGVuc2l0eSBvZiBvY2N1cnJlbmNlcyAobnVtYmVyL015KSIpICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWU9IkFjY2VwdGVkIG5hbWUgY291bnQiKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpKSArCiAgZ2d0aXRsZSgiRGlzdHJpYnV0aW9ucyBvY2N1cnJlbmNlIGRlbnNpdHksIGJ5IGFjY2VwdGVkIHJhbmsiKSArCiAgZmFjZXRfZ3JpZChhY2NlcHRlZF9yYW5rIH4gLiwgc2NhbGVzID0gImZyZWUiKQpgYGAKCiRcdG8kIERlbnNpdHkgbG9naWNhbGx5IGluY3JlYXNlcyBhcyB0YXhhIHJhbmtzIGluY3JlYXNlLgoKIyMgQ29ycmVsYXRpb24gYmV0d2VlbiB0aW1lIHJhbmdlIGFuZCBhZ2UKCklmIHdlIHdhbnQgdG8gY29ycmVjdCBzcGVjaWVzIGFidW5kYW5jZSBkaWZmZXJlbmNlcyBiYXNlZCBvbiB0aGUgbnVtYmVyIG9mIG9jY3VycmVuY2VzIGluIHRoZSB0aW1lIHJhbmdlICgiZGVuc2l0eSIpLCB0aG9zZSBmYWN0b3JzIHNob3VsZCBub3QgZGVwZW5kIG9uIHRpbWUgaW4gb3JkZXIgdG8gYXZvaWQgcGVuYWxpemluZyBwZXJpb2RzIHdpdGggaGlnaGVyIGRlbnNpdGllcy4KCmBgYHtyfQpjb25kaXRpb25zIDwtIENldGFjZWFfb2NjJGFjY2VwdGVkX3JhbmsgPT0ic3BlY2llcyIgJiBDZXRhY2VhX29jYyRhZ2VfcmFuZ2U8MTAKCiMgS2VlcCBvbmx5IG9uZSBwb2ludCBieSBpZGVudGljYWwgdGltZSBpbnRlcnZhbAoKYWdlX2ludGVydmFsX3RhYmxlIDwtIHRhYmxlKENldGFjZWFfb2NjW2NvbmRpdGlvbnMsXSRhZ2VfaW50ZXJ2YWwpCgppbnRlcnZhbF9tZWFuX2FnZSA8LSBzYXBwbHkobmFtZXMoYWdlX2ludGVydmFsX3RhYmxlKSwgZnVuY3Rpb24oeCl7Q2V0YWNlYV9vY2NbY29uZGl0aW9ucyAmIENldGFjZWFfb2NjJGFnZV9pbnRlcnZhbD09eCxdJGFnZV9tZWFuWzFdfSkKCmludGVydmFsX3JhbmdlIDwtIHNhcHBseShuYW1lcyhhZ2VfaW50ZXJ2YWxfdGFibGUpLCBmdW5jdGlvbih4KXtDZXRhY2VhX29jY1tjb25kaXRpb25zICYgQ2V0YWNlYV9vY2MkYWdlX2ludGVydmFsPT14LF0kYWdlX3JhbmdlWzFdfSkKCmRmIDwtIGRhdGEuZnJhbWUoeD1pbnRlcnZhbF9tZWFuX2FnZSwKICAgICAgICAgICAgICAgICB5PWludGVydmFsX3JhbmdlKQoKZ2dwbG90KGRmLCBhZXMoeD14LCB5PXkpKSArIAogIGdlb21fcG9pbnQoYWxwaGE9MC41KSArCiAgZ2VvbV9zbW9vdGgoZm9ybXVsYSA9IHl+eCwgc3BhbiA9IDAuOSwgbWV0aG9kID0gJ2xvZXNzJykgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIlRpbWUgKE15KSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobmFtZSA9ICJVbmNlcnRhaW50eSByYW5nZSIpICsKICBnZ3RpdGxlKCJTbW9vdGhlZCBjb3JyZXNwb25kYW5jZSBiZXR3ZWVuIHRpbWUgcmFuZ2UgYW5kIGFnZSIpCgojIEtlZXAgb25seSBvbmUgcG9pbnQgYnkgaWRlbnRpY2FsIGNvbWJpbmVkIHRpbWUgaW50ZXJ2YWwKYWdlX2NvbWJpbmVkX2ludGVydmFsX3RhYmxlIDwtIHRhYmxlKENldGFjZWFfb2NjW2NvbmRpdGlvbnMsXSRhZ2VfY29tYmluZWRfaW50ZXJ2YWwpCgpjb21iaW5lZF9pbnRlcnZhbF9tZWFuX2FnZSA8LSBzYXBwbHkobmFtZXMoYWdlX2NvbWJpbmVkX2ludGVydmFsX3RhYmxlKSwgZnVuY3Rpb24oeCl7Q2V0YWNlYV9vY2NbY29uZGl0aW9ucyAmIENldGFjZWFfb2NjJGFnZV9jb21iaW5lZF9pbnRlcnZhbD09eCxdJGFnZV9jb21iaW5lZF9tZWFuWzFdfSkKCmNvbWJpbmVkX2ludGVydmFsX3JhbmdlIDwtIHNhcHBseShuYW1lcyhhZ2VfY29tYmluZWRfaW50ZXJ2YWxfdGFibGUpLCBmdW5jdGlvbih4KXtDZXRhY2VhX29jY1tjb25kaXRpb25zICYgQ2V0YWNlYV9vY2MkYWdlX2NvbWJpbmVkX2ludGVydmFsPT14LF0kYWdlX2NvbWJpbmVkX3JhbmdlWzFdfSkKCmNvbWJpbmVkX2RmIDwtIGRhdGEuZnJhbWUoeD1jb21iaW5lZF9pbnRlcnZhbF9tZWFuX2FnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICB5PWNvbWJpbmVkX2ludGVydmFsX3JhbmdlKQoKZ2dwbG90KGNvbWJpbmVkX2RmLCBhZXMoeD14LCB5PXkpKSArIAogIGdlb21fcG9pbnQoYWxwaGE9MC41KSArCiAgZ2VvbV9zbW9vdGgoZm9ybXVsYSA9IHl+eCwgc3BhbiA9IDAuOSwgbWV0aG9kID0gJ2xvZXNzJykgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJUaW1lIChNeSkiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKG5hbWUgPSAiQ29tYmluZWQgdW5jZXJ0YWludHkgcmFuZ2UiKSArCiAgZ2d0aXRsZSgiU21vb3RoZWQgY29ycmVzcG9uZGFuY2UgYmV0d2VlbiBjb21iaW5lZCB0aW1lIHJhbmdlIGFuZCBhZ2UiKQpgYGAKCiRcdG8kIEl0IHNlZW1zIHRoYXQgYWdlIHJhbmdlIHZhcmllcyBpbXBvcnRhbnRseSB3aXRoIHRpbWUsIGJ1dCB3aGVuIHRha2luZyB0aGUgZnVsbCBjb21iaW5lZCByYW5nZSBpbnRvIGFjY291bnQgdGhlIGNvcnJlbGF0aW9uIHNlZW1zIHF1aXRlIHdlYWsgYWZ0ZXIgdGhlIGZpcnN0IG1pbGxpb24geWVhcnMuCgpMZXQncyBsb29rIGF0IHRoZSBkZW5zaXR5IGRpcmVjdGx5LCBiZWNhdXNlIHRoaXMgaXMgd2hhdCBpcyBpbnRlcmVzdGluZyB1cyBkaXJlY3RseS4KCmBgYHtyfQpjb25kaXRpb25zIDwtIENldGFjZWFfb2NjJGFjY2VwdGVkX3JhbmsgPT0ic3BlY2llcyIgJiBDZXRhY2VhX29jYyRhZ2VfcmFuZ2U8MTAKCiMgRnVuY3Rpb24gdG8gcGxvdCBsaW5lYXIgcmVncmVzc2lvbiBjb2VmZmljaWVudHMKbG1fZXFuIDwtIGZ1bmN0aW9uKGRmKXsKICAgIG0gPC0gbG0oeSB+IHgsIGRmKTsKICAgIGVxIDwtIHN1YnN0aXR1dGUoaXRhbGljKHkpID09IGEgKyBiICUuJSBpdGFsaWMoeCkqIiwifn5pdGFsaWMocileMn4iPSJ+cjIsIAogICAgICAgICBsaXN0KGEgPSBmb3JtYXQodW5uYW1lKGNvZWYobSlbMV0pLCBkaWdpdHMgPSAyKSwKICAgICAgICAgICAgICBiID0gZm9ybWF0KHVubmFtZShjb2VmKG0pWzJdKSwgZGlnaXRzID0gMiksCiAgICAgICAgICAgICByMiA9IGZvcm1hdChzdW1tYXJ5KG0pJHIuc3F1YXJlZCwgZGlnaXRzID0gMykpKQogICAgYXMuY2hhcmFjdGVyKGFzLmV4cHJlc3Npb24oZXEpKTsKfQoKIyBLZWVwIG9ubHkgb25lIHBvaW50IGJ5IGlkZW50aWNhbCB0aW1lIGludGVydmFsCmFnZV9pbnRlcnZhbF90YWJsZSA8LSB0YWJsZShDZXRhY2VhX29jY1tjb25kaXRpb25zLF0kYWdlX2ludGVydmFsKQoKaW50ZXJ2YWxfbWVhbl9hZ2UgPC0gc2FwcGx5KG5hbWVzKGFnZV9pbnRlcnZhbF90YWJsZSksIGZ1bmN0aW9uKHgpe0NldGFjZWFfb2NjW2NvbmRpdGlvbnMgJiBDZXRhY2VhX29jYyRhZ2VfaW50ZXJ2YWw9PXgsXSRhZ2VfbWVhblsxXX0pCgppbnRlcnZhbF9kZW5zaXR5IDwtIHNhcHBseShuYW1lcyhhZ2VfaW50ZXJ2YWxfdGFibGUpLCBmdW5jdGlvbih4KXtDZXRhY2VhX29jY1tjb25kaXRpb25zICYgQ2V0YWNlYV9vY2MkYWdlX2ludGVydmFsPT14LF0kb2NjdXJyZW5jZV9kZW5zaXR5WzFdfSkKCmRmX2RlbnNpdHkgPC0gZGF0YS5mcmFtZSh4PWludGVydmFsX21lYW5fYWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgeT1pbnRlcnZhbF9kZW5zaXR5KQoKZ2dwbG90KGRmX2RlbnNpdHksIGFlcyh4PXgsIHk9eSkpICsgCiAgZ2VvbV9wb2ludChhbHBoYT0wLjUpICsKICBnZW9tX3Ntb290aChmb3JtdWxhID0geX54LCBtZXRob2Q9bG0pICsgCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiVGltZSAoTXkpIikgKwogIHNjYWxlX3lfY29udGludW91cyhuYW1lID0gIkNvbWJpbmVkIGRlbnNpdHkiKSArCiAgZ2d0aXRsZSgiQ29ycmVsYXRpb24gYmV0d2VlbiBkZW5zaXR5IGFuZCBhZ2UiKSArCiAgZ2VvbV90ZXh0KHggPSAzNSwgeSA9IDI1LCBsYWJlbCA9IGxtX2VxbihkZl9kZW5zaXR5KSwgcGFyc2UgPSBUUlVFKQoKIyBLZWVwIG9ubHkgb25lIHBvaW50IGJ5IGlkZW50aWNhbCBjb21iaW5lZCB0aW1lIGludGVydmFsCmFnZV9jb21iaW5lZF9pbnRlcnZhbF90YWJsZSA8LSB0YWJsZShDZXRhY2VhX29jY1tjb25kaXRpb25zLF0kYWdlX2NvbWJpbmVkX2ludGVydmFsKQoKY29tYmluZWRfaW50ZXJ2YWxfbWVhbl9hZ2UgPC0gc2FwcGx5KG5hbWVzKGFnZV9jb21iaW5lZF9pbnRlcnZhbF90YWJsZSksIGZ1bmN0aW9uKHgpe0NldGFjZWFfb2NjW2NvbmRpdGlvbnMgJiBDZXRhY2VhX29jYyRhZ2VfY29tYmluZWRfaW50ZXJ2YWw9PXgsXSRhZ2VfY29tYmluZWRfbWVhblsxXX0pCgpDZXRhY2VhX29jYyRvY2N1cnJlbmNlX2NvbWJpbmVkX2RlbnNpdHkgPC0gQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfbmFtZV9jb3VudC9DZXRhY2VhX29jYyRhZ2VfY29tYmluZWRfcmFuZ2UKCmNvbWJpbmVkX2ludGVydmFsX2RlbnNpdHkgPC0gc2FwcGx5KG5hbWVzKGFnZV9jb21iaW5lZF9pbnRlcnZhbF90YWJsZSksIGZ1bmN0aW9uKHgpe0NldGFjZWFfb2NjW2NvbmRpdGlvbnMgJiBDZXRhY2VhX29jYyRhZ2VfY29tYmluZWRfaW50ZXJ2YWw9PXgsXSRvY2N1cnJlbmNlX2NvbWJpbmVkX2RlbnNpdHlbMV19KQoKY29tYmluZWRfZGZfZGVuc2l0eSA8LSBkYXRhLmZyYW1lKHg9Y29tYmluZWRfaW50ZXJ2YWxfbWVhbl9hZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5PWNvbWJpbmVkX2ludGVydmFsX2RlbnNpdHkpCgpnZ3Bsb3QoY29tYmluZWRfZGZfZGVuc2l0eSwgYWVzKHg9eCwgeT15KSkgKyAKICBnZW9tX3BvaW50KGFscGhhPTAuNSkgKwogIGdlb21fc21vb3RoKGZvcm11bGEgPSB5fngsIG1ldGhvZD1sbSkgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJUaW1lIChNeSkiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKG5hbWUgPSAiQ29tYmluZWQgZGVuc2l0eSIpICsKICBnZ3RpdGxlKCJDb3JyZWxhdGlvbiBiZXR3ZWVuIGNvbWJpbmVkIGRlbnNpdHkgYW5kIGFnZSIpICsKICBnZW9tX3RleHQoeCA9IDE1LCB5ID0gNiwgbGFiZWwgPSBsbV9lcW4oY29tYmluZWRfZGZfZGVuc2l0eSksIHBhcnNlID0gVFJVRSkKYGBgCgokXHRvJCBUaGUgZGVuc2l0eSBiYXNlZCBvbiBjb21iaW5lZCByYW5nZXMgaXMgbXVjaCBsZXNzIHRpbWUtZGVwZW5kYW50IHRoYW4gdGhlIGRlbnNpdHkgYmFzZWQgb24gaW5pdGlhbCByYW5nZSBhZ2VzLiBXZSB3aWxsIHRoZXJlZm9yZSB1c2UgdGhlIGNvbWJpbmVkIGRlbnNpdHkgZm9yIG91ciBjb3JyZWN0aW9ucy4KCiMjIFN1Yi1zYW1wbGluZyBvZiBvY2N1cnJlbmNlcyB3aXRoIGEgbm9ybWFsaXplZCBkZW5zaXR5IGFsb25nIHRoZSBjb21iaW5lZCByYW5nZXMKIyMjIENvbXBhcmUgZGVuc2l0aWVzIGZvciBzaW5nbGUgdnMuIGNvbWJpbmVkIHJhbmdlcy4KCmBgYHtyIGZpZy5oZWlnaHQ9Nn0KY29uZGl0aW9ucyA8LSAhKENldGFjZWFfb2NjJGFjY2VwdGVkX3JhbmsgJWluJSBjKCJzdWJzcGVjaWVzIiwgImluZnJhb3JkZXIiKSkgJiBDZXRhY2VhX29jYyRhZ2VfcmFuZ2U8MTAKCmdncGxvdChDZXRhY2VhX29jY1tjb25kaXRpb25zLF0sIGFlcyh4PW9jY3VycmVuY2VfZGVuc2l0eSwgZmlsbD1mYWN0b3IoYWNjZXB0ZWRfbmFtZV9jb3VudCkpKSArCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGg9MC4xKSArCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zPSJsb2cxMCIsIG5hbWU9IkRlbnNpdHkgb2Ygb2NjdXJyZW5jZXMgKG51bWJlci9NeSkiKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSJBY2NlcHRlZCBuYW1lIGNvdW50IikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIGdndGl0bGUoIkRpc3RyaWJ1dGlvbnMgb2Ygb2NjdXJyZW5jZSBkZW5zaXR5LCBieSBhY2NlcHRlZCByYW5rIikgKwogIGZhY2V0X2dyaWQoYWNjZXB0ZWRfcmFuayB+IC4sIHNjYWxlcyA9ICJmcmVlIikKCmdncGxvdChDZXRhY2VhX29jY1tjb25kaXRpb25zLF0sIGFlcyh4PW9jY3VycmVuY2VfY29tYmluZWRfZGVuc2l0eSwgZmlsbD1mYWN0b3IoYWNjZXB0ZWRfbmFtZV9jb3VudCkpKSArCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGg9MC4wNSkgKwogIHNjYWxlX3hfY29udGludW91cyh0cmFucz0ibG9nMTAiLCBuYW1lPSJDb21iaW5lZCBkZW5zaXR5IG9mIG9jY3VycmVuY2VzIChudW1iZXIvTXkpIikgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iQWNjZXB0ZWQgbmFtZSBjb3VudCIpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCkpICsKICBnZ3RpdGxlKCJEaXN0cmlidXRpb25zIG9mIGNvbWJpbmVkIG9jY3VycmVuY2UgZGVuc2l0eSwgYnkgYWNjZXB0ZWQgcmFuayIpICsKICBmYWNldF9ncmlkKGFjY2VwdGVkX3JhbmsgfiAuLCBzY2FsZXMgPSAiZnJlZSIpCmBgYAoKJFx0byQgRGVuc2l0aWVzIGFyZSBzbWFsbGVyIGFuZCBtb3JlIGNvbmNlbnRyYXRlZCB3aXRoIHRoZSBjb21iaW5lZCByYW5nZXMgKGxhcmdlciB0aW1lIHNwYW4gKyBsZXNzIHJhbmdlcyBpbiB0b3RhbCBiZWNhdXNlIG9mIHRoZSBjb2xsZXBzZXMgaW50byB1bmlxdWUgcmFuZ2VzKS4KCiMjIyBDb21wYXJlIGRlbnNpdGllcyBieSBhY2NlcHRlZCBuYW1lIGNvdW50IChzcGVjaWVzIG9ubHkpCgpMZXQncyBmb2N1cyBub3cgb24gdGhlIG9jY3VycmVuY2VzIGFjY2VwdGVkIGF0IHRoZSBzcGVjaWVzIGxldmVsIGJlY2F1c2UgdGhleSBhcmUgdGhlIG9uZSBmb3Igd2hpY2ggd2UgY2FuIGNvcnJlY3QgdGhlIGFidW5kYW5jZSBiaWFzIGJ5IHN1YnNhbXBsaW5nIHRoZSBtb3N0IGNvbmNlbnRyYXRlZCBjb21iaW5lZCBpbnRlcnZhbHMuCgpgYGB7ciBmaWcuaGVpZ2h0PTZ9CmNvbmRpdGlvbnMgPC0gQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayA9PSJzcGVjaWVzIiAmIENldGFjZWFfb2NjJGFnZV9yYW5nZTwxMAoKZ2dwbG90KENldGFjZWFfb2NjW2NvbmRpdGlvbnMsXSwgYWVzKHg9b2NjdXJyZW5jZV9kZW5zaXR5LCBmaWxsPWZhY3RvcihhY2NlcHRlZF9uYW1lX2NvdW50KSkpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aD0wLjEpICsKICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnM9ImxvZzEwIiwgbmFtZT0iRGVuc2l0eSBvZiBvY2N1cnJlbmNlcyAobnVtYmVyL015KSIpICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWU9IkFjY2VwdGVkIG5hbWUgY291bnQiKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpKSArCiAgZ2d0aXRsZSgiRGlzdHJpYnV0aW9ucyBvZiBvY2N1cnJlbmNlIGRlbnNpdHkgYW1vbmcgc3BlY2llcyIpICsKICBmYWNldF9ncmlkKGFjY2VwdGVkX25hbWVfY291bnQgfiAuLCBzY2FsZXMgPSAiZnJlZSIpCgpnZ3Bsb3QoQ2V0YWNlYV9vY2NbY29uZGl0aW9ucyxdLCBhZXMoeD1vY2N1cnJlbmNlX2NvbWJpbmVkX2RlbnNpdHksIGZpbGw9ZmFjdG9yKGFjY2VwdGVkX25hbWVfY291bnQpKSkgKwogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoPTAuMDUpICsKICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnM9ImxvZzEwIiwgbmFtZT0iQ29tYmluZWQgZGVuc2l0eSBvZiBvY2N1cnJlbmNlcyAobnVtYmVyL015KSIpICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWU9IkFjY2VwdGVkIG5hbWUgY291bnQiKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpKSArCiAgZ2d0aXRsZSgiRGlzdHJpYnV0aW9ucyBvZiBjb21iaW5lZCBvY2N1cnJlbmNlIGRlbnNpdHkgYW1vbmcgc3BlY2llcyIpICsKICBmYWNldF9ncmlkKGFjY2VwdGVkX25hbWVfY291bnQgfiAuLCBzY2FsZXMgPSAiZnJlZSIpCmBgYAoKJFx0byQgVGhlaXIgaXMgYSBodWdlIHNwYW4gb2YgZGVuc2l0aWVzIGRyaXZlbiBieSB0aGUgbnVtYmVyIG9mIG9jY3VycmVuY2VzIGZvciB0aGUgc2FtZSBzcGVjaWVzIHRoYXQgd2UgY2FuIHJlZHVjZSBieSBzdWJzYW1wbGluZyB0aGUgbW9zdCBjb25jZW50cmF0ZWQgaW50ZXJ2YWxzLgoKIyMjIEltcGFjdCBvZiBjb3JyZWN0aW5nIHN1YnNhbXBsaW5nIG9uIGRlbnNpdHkgZGlzdHJpYnV0aW9ucyAoc3BlY2llcyBvbmx5KQoKYGBge3IgZmlnLmhlaWdodD02fQpjb25kaXRpb25zIDwtIENldGFjZWFfb2NjJGFjY2VwdGVkX3JhbmsgPT0ic3BlY2llcyIgJiBDZXRhY2VhX29jYyRhZ2VfcmFuZ2U8MTAKCmdncGxvdChDZXRhY2VhX29jY1tjb25kaXRpb25zLF0sIGFlcyh4PW9jY3VycmVuY2VfY29tYmluZWRfZGVuc2l0eSwgZmlsbD1mYWN0b3IoYWNjZXB0ZWRfbmFtZV9jb3VudCkpKSArCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGg9MC4wNSkgKwogIHNjYWxlX3hfY29udGludW91cyh0cmFucz0ibG9nMTAiLCBuYW1lPSJDb21iaW5lZCBkZW5zaXR5IG9mIG9jY3VycmVuY2VzIChudW1iZXIvTXkpIikgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iQWNjZXB0ZWQgbmFtZSBjb3VudCIpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCkpICsKICBnZ3RpdGxlKHBhc3RlKCJEaXN0cmlidXRpb25zIG9mIGNvbWJpbmVkIG9jY3VycmVuY2UgZGVuc2l0eSBhbW9uZyBzcGVjaWVzIChuID0gIiwgZGltKENldGFjZWFfb2NjW2NvbmRpdGlvbnMsXSlbMV0sICIpIiwgc2VwPSIiKSkgKwogIGZhY2V0X2dyaWQoYWNjZXB0ZWRfbmFtZV9jb3VudCB+IC4sIHNjYWxlcyA9ICJmcmVlIikKCiMgQWRkIGF0IGxlYXN0IG9uZSBvY2N1cnJlbmNlIG9mIGVhY2ggc3BlY2llcwpDZXRhY2VhX29jY19zYW1wbGVkIDwtIGMoKQpDZXRhY2VhX29jY19ub3RzYW1wbGVkIDwtIGMoKQpmb3IgKGkgaW4gYXMubnVtZXJpYyhyb3cubmFtZXMoQ2V0YWNlYV9vY2NbY29uZGl0aW9ucyxdKSkpewogIHJvdyA8LSBDZXRhY2VhX29jY1thcy5jaGFyYWN0ZXIoaSksXQogIGlmICghKHJvdyRhY2NlcHRlZF9uYW1lICVpbiUgQ2V0YWNlYV9vY2Nfc2FtcGxlZCRhY2NlcHRlZF9uYW1lKSl7CiAgICBDZXRhY2VhX29jY19zYW1wbGVkIDwtIHJiaW5kKENldGFjZWFfb2NjX3NhbXBsZWQsIHJvdykKICB9ZWxzZXsKICAgIENldGFjZWFfb2NjX25vdHNhbXBsZWQgPC0gcmJpbmQoQ2V0YWNlYV9vY2Nfbm90c2FtcGxlZCwgcm93KQogIH0KfQoKIyBBZGQgb2NjdXJyZW5jZXMgaW4gdGhlIHJlbWFuaW5nIG9uZXMsIGJ5IHVuZGVyd2VpZ2h0aW5nIGRlbnNlIHNwZWNpZXMKQ2V0YWNlYV9vY2Nfc2FtcGxlZCA8LSByYmluZChDZXRhY2VhX29jY19zYW1wbGVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYW1wbGVfbihDZXRhY2VhX29jY19ub3RzYW1wbGVkLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZT04MDAtZGltKENldGFjZWFfb2NjX3NhbXBsZWQpWzFdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3ZWlnaHQ9MS9DZXRhY2VhX29jY19ub3RzYW1wbGVkJG9jY3VycmVuY2VfY29tYmluZWRfZGVuc2l0eSoqMykpCgpDZXRhY2VhX29jY19zYW1wbGVkJG1pbl9taW5fbWEgPC0gYXBwbHkoQ2V0YWNlYV9vY2Nfc2FtcGxlZCwgMSwgZnVuY3Rpb24oWCl7bWluKENldGFjZWFfb2NjX3NhbXBsZWRbQ2V0YWNlYV9vY2Nfc2FtcGxlZCRhY2NlcHRlZF9uYW1lPT1YWyJhY2NlcHRlZF9uYW1lIl0sXSRtaW5fbWEpfSkKQ2V0YWNlYV9vY2Nfc2FtcGxlZCRtYXhfbWF4X21hIDwtIGFwcGx5KENldGFjZWFfb2NjX3NhbXBsZWQsIDEsIGZ1bmN0aW9uKFgpe21heChDZXRhY2VhX29jY19zYW1wbGVkW0NldGFjZWFfb2NjX3NhbXBsZWQkYWNjZXB0ZWRfbmFtZT09WFsiYWNjZXB0ZWRfbmFtZSJdLF0kbWF4X21hKX0pCkNldGFjZWFfb2NjX3NhbXBsZWQkYWdlX2NvbWJpbmVkX3JhbmdlIDwtIENldGFjZWFfb2NjX3NhbXBsZWQkbWF4X21heF9tYS1DZXRhY2VhX29jY19zYW1wbGVkJG1pbl9taW5fbWEKQ2V0YWNlYV9vY2Nfc2FtcGxlZCRhY2NlcHRlZF9uYW1lX2NvdW50IDwtIHNhcHBseShDZXRhY2VhX29jY19zYW1wbGVkJGFjY2VwdGVkX25hbWUsIGZ1bmN0aW9uKHgpe3RhYmxlKENldGFjZWFfb2NjX3NhbXBsZWQkYWNjZXB0ZWRfbmFtZSlbeF19KQpDZXRhY2VhX29jY19zYW1wbGVkJG9jY3VycmVuY2VfY29tYmluZWRfZGVuc2l0eSA8LSBDZXRhY2VhX29jY19zYW1wbGVkJGFjY2VwdGVkX25hbWVfY291bnQvQ2V0YWNlYV9vY2Nfc2FtcGxlZCRhZ2VfY29tYmluZWRfcmFuZ2UKCgpnZ3Bsb3QoQ2V0YWNlYV9vY2Nfc2FtcGxlZCwgYWVzKHg9b2NjdXJyZW5jZV9jb21iaW5lZF9kZW5zaXR5LCBmaWxsPWZhY3RvcihhY2NlcHRlZF9uYW1lX2NvdW50KSkpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aD0wLjA1KSArCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zPSJsb2cxMCIsIG5hbWU9IkNvbWJpbmVkIGRlbnNpdHkgb2Ygb2NjdXJyZW5jZXMgKG51bWJlci9NeSkiLCBsaW1pdHM9YygwLjEsIDEwMDApKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSJBY2NlcHRlZCBuYW1lIGNvdW50IikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIGdndGl0bGUocGFzdGUoIkRpc3RyaWJ1dGlvbnMgb2YgY29tYmluZWQgb2NjdXJyZW5jZSBkZW5zaXR5IGFtb25nIHNwZWNpZXMsIGFmdGVyIHNhbXBsaW5nIChuID0gIiwgZGltKENldGFjZWFfb2NjX3NhbXBsZWQpWzFdLCAiKSIsIHNlcD0iIikpICsKICBmYWNldF9ncmlkKGFjY2VwdGVkX25hbWVfY291bnQgfiAuLCBzY2FsZXMgPSAiZnJlZSIpCmBgYAoKJFx0byQgU3Vic2FtcGxpbmcgc3VjY2Vzc2Z1bGx5IHJlZHVjZXMgdGhlIGRlbnNpdHkgc3BhbiBmcm9tIDIgdG8gMSBvcmRlciBvZiBtYWduaXR1ZGUuCgojIyMgSW1wYWN0IG9mIHN1YnNhbXBsaW5nIG9uIG9jY3VycmVuY2VzIHJlcGFydGl0aW9uIChzcGVjaWVzIG9ubHkpCgpTZWUgd2hhdCBvdXIgZGlzdHJpYnV0aW9ucyBsb29vayBsaWtlIGFmdGVyIHN1YnNhbXBsaW5nIDoKCmBgYHtyIGZpZy5oZWlnaHQ9NX0KYnJlYWtzIDwtIGMoMC4xMjUsMC4yNSwwLjUsMSwyLDQsOCwxNikKCmdncGxvdChDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rID09InNwZWNpZXMiICYgQ2V0YWNlYV9vY2MkYWdlX3JhbmdlPDEwLF0sIGFlcyh4PS1tYXhfbWEsIHk9YWNjZXB0ZWRfbmFtZSkpICsKICBnZW9tX3NlZ21lbnQoYWVzKHggPSAtbWF4X21heF9tYSwgeSA9IHJlb3JkZXIoYWNjZXB0ZWRfbmFtZSwgLWFnZV9jb21iaW5lZF9tZWFuKSwgeGVuZCA9IC1taW5fbWluX21hLCB5ZW5kPXJlb3JkZXIoYWNjZXB0ZWRfbmFtZSwgLWFnZV9jb21iaW5lZF9tZWFuKSwgY29sb3I9b2NjdXJyZW5jZV9jb21iaW5lZF9kZW5zaXR5KSwgYXJyb3c9YXJyb3coZW5kcyA9ICJib3RoIiwgYW5nbGU9OTAsIGxlbmd0aCA9IHVuaXQoMSwgIm1tIikpLCBhbHBoYT0wLjUpICsKICBnZW9tX3BvaW50KGFlcyh4PS1hZ2VfcnVuaWYpLCBjb2w9InJlZCIsIGNleD0wLjUsIGFscGhhPTAuNSkgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIlRpbWUgKE15KSIpICsKICBzY2FsZV95X2Rpc2NyZXRlKG5hbWUgPSAiU3BlY2llcyIpICsKICBsYWJzKGNvbG91cj0iT2NjdXJyZW5jZVxuZGVuc2l0eSIpICsKICB0aGVtZShheGlzLnRleHQueT1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcy55PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCkpICsKICBzY2FsZV9jb2xvcl9ncmFkaWVudG4oY29sb3VycyA9IGMoImRhcmtibHVlIiwgImZvcmVzdGdyZWVuIiwgImJsYWNrIiksIHRyYW5zPSJsb2ciLCBicmVha3M9YnJlYWtzLCBsYWJlbHM9YnJlYWtzKSArIAogIGdndGl0bGUocGFzdGUoIkRpc3RyaWJ1dGlvbnMgb2Ygc3BlY2llcyBmb3NzaWwgYWdlIHJhbmdlcywgYmVmb3JlIGNvcnJlY3Rpbmcgc2FtcGxpbmcgKG4gPSAiLCBkaW0oQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayA9PSJzcGVjaWVzIiAmIENldGFjZWFfb2NjJGFnZV9yYW5nZTwxMCxdKVsxXSwgIikiLCBzZXA9IiIpKQoKZ2dwbG90KENldGFjZWFfb2NjX3NhbXBsZWQsIGFlcyh4PS1tYXhfbWEsIHk9YWNjZXB0ZWRfbmFtZSkpICsKICBnZW9tX3NlZ21lbnQoYWVzKHggPSAtbWF4X21heF9tYSwgeSA9IHJlb3JkZXIoYWNjZXB0ZWRfbmFtZSwgLWFnZV9jb21iaW5lZF9tZWFuKSwgeGVuZCA9IC1taW5fbWluX21hLCB5ZW5kPXJlb3JkZXIoYWNjZXB0ZWRfbmFtZSwgLWFnZV9jb21iaW5lZF9tZWFuKSwgY29sb3I9b2NjdXJyZW5jZV9jb21iaW5lZF9kZW5zaXR5KSwgYXJyb3c9YXJyb3coZW5kcyA9ICJib3RoIiwgYW5nbGU9OTAsIGxlbmd0aCA9IHVuaXQoMSwgIm1tIikpLCBhbHBoYT0wLjUpICsKICBnZW9tX3BvaW50KGFlcyh4PS1hZ2VfcnVuaWYpLCBjb2w9InJlZCIsIGNleD0wLjUsIGFscGhhPTAuNSkgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIlRpbWUgKE15KSIpICsKICBzY2FsZV95X2Rpc2NyZXRlKG5hbWUgPSAiU3BlY2llcyIpICsKICBsYWJzKGNvbG91cj0iT2NjdXJyZW5jZVxuZGVuc2l0eSIpICsKICB0aGVtZShheGlzLnRleHQueT1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcy55PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCkpICsKICBzY2FsZV9jb2xvcl9ncmFkaWVudG4oY29sb3VycyA9IGMoImRhcmtibHVlIiwgImZvcmVzdGdyZWVuIiwgImJsYWNrIiksIHRyYW5zPSJsb2ciLCBicmVha3M9YnJlYWtzLCBsYWJlbHM9YnJlYWtzKSArIAogIGdndGl0bGUocGFzdGUoIkRpc3RyaWJ1dGlvbnMgb2Ygc3BlY2llcyBmb3NzaWwgYWdlIHJhbmdlcywgYWZ0ZXIgY29ycmVjdGluZyBzYW1wbGluZyAobiA9ICIsIGRpbShDZXRhY2VhX29jY19zYW1wbGVkKVsxXSwgIikiLCBzZXA9IiIpKQpgYGAKCiRcdG8kIFNvbWUgaGlnaGx5IGRlbnNlIGNsdXN0ZXIgYmVjYW1lIG11Y2ggbW9yZSBzaW1pbGFyIHRvIHRoZSBvdGhlcnMuCgpgYGB7ciBmaWcuaGVpZ2h0PTV9CmNvbmRpdGlvbnMgPC0gQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayA9PSJzcGVjaWVzIiAmIENldGFjZWFfb2NjJGFnZV9yYW5nZTwxMAoKZ2dwbG90KENldGFjZWFfb2NjW2NvbmRpdGlvbnMsXSwgYWVzKHg9LWFnZV9ydW5pZikpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuNSwgYWxwaGE9MC41LCBmaWxsPSJyZWQiKSArCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiVGltZSAoTXkpIikgKwogIHNjYWxlX3lfY29udGludW91cyhuYW1lID0gIk51bWJlciBvZiBvY2N1cnJlbmNlcyIpICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWU9IkFjY2VwdGVkIHJhbmsiKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpKSArCiAgZ2d0aXRsZShwYXN0ZSgiRXZvbHV0aW9uIG9mIHRoZSBzcGVjaWVzIG9jY3VycmVuY2UgbnVtYmVyIHRocm91Z2ggdGltZSAobiA9ICIsIGRpbShDZXRhY2VhX29jY1tjb25kaXRpb25zLF0pWzFdLCAiKSIsIHNlcD0iIikpCgpnZ3Bsb3QoQ2V0YWNlYV9vY2Nfc2FtcGxlZCwgYWVzKHg9LWFnZV9ydW5pZikpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuNSwgYWxwaGE9MC41LCBmaWxsPSJibHVlIikgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIlRpbWUgKE15KSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobmFtZSA9ICJOdW1iZXIgb2Ygb2NjdXJyZW5jZXMiKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSJBY2NlcHRlZCByYW5rIikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIGdndGl0bGUocGFzdGUoIkV2b2x1dGlvbiBvZiB0aGUgc3BlY2llcyBvY2N1cnJlbmNlIG51bWJlciB0aHJvdWdoIHRpbWUsIGFmdGVyIGNvcnJlY3Rpb24gc2FtcGxpbmcgKG4gPSAiLCBkaW0oQ2V0YWNlYV9vY2Nfc2FtcGxlZClbMV0sICIpIiwgc2VwPSIiKSkKYGBgCgpJZiB3ZSBzdXBlcnBvc2UgdGhlc2UgMiBwbG90cyA6CgpgYGB7ciBmaWcuaGVpZ2h0PTV9CmNvbmRpdGlvbnMgPC0gQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayA9PSJzcGVjaWVzIiAmIENldGFjZWFfb2NjJGFnZV9yYW5nZTwxMAoKcDEgPC0gZ2dwbG90KENldGFjZWFfb2NjW2NvbmRpdGlvbnMsXSwgYWVzKHg9LWFnZV9ydW5pZikpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuNSwgYWxwaGE9MC41LCBmaWxsPSJyZWQiKSArCiAgdGhlbWVfdm9pZCgpCgpwMiA8LSBnZ3Bsb3QoQ2V0YWNlYV9vY2Nfc2FtcGxlZCwgYWVzKHg9LWFnZV9ydW5pZikpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuNSwgYWxwaGE9MC41LCBmaWxsPSJibHVlIikgKwogIHRoZW1lX3ZvaWQoKQoKcDEgKyBhbm5vdGF0aW9uX2N1c3RvbShnZ3Bsb3RHcm9iKHAyKSkKYGBgCgokXHRvJCBXZSBnZXQgdGhlIG5ldyBzcGVjaWVzIG9jY3VycmVuY2UgcmVwYXJ0aXRpb24gYWZ0ZXIgc3Vic2FtcGxpbmcgY29ycmVjdGlvbiwgdGhhdCBjb3VsZCBiZSB1c2VkIGZvciBkb2luZyBpbmZlcmVuY2Ugd2l0aCB0aGUgb2NjdXJyZW5jZSBiaXJ0aC1kZWF0aCBtb2RlbC4KCiMgTmV3IGRldmVsb3BtZW50cwoKIyMgQ29tcGFyZSB3aXRoIGEgUG9pc3NvbiBzYW1wbGluZyBwcm9jZXNzCgpJbiBvcmRlciB0byBjaGVjayBpZiB0aGUgZGF0YSBmaXQgb3VyIGFzc3VtcHRpb25zIG9mIGNvbnN0YW50LWZvc3NpbGlzYXRpb24tcmF0ZSBQb2lzc29uIHNhbXBsaW5nIHdlIGNvbXBhcmUgdGhlIG9ic2VydmVkIG9jY3VycmVuY2VzIGRpc3RyaWJ1dGlvbnMgd2l0aCB0aGUgZXhwZWN0ZWQgb25lcy4gU3BlY2lmaWNhbGx5LCB3ZSB3aWxsIGxvb2sgYXQgdGhlIG51bWJlciBvZiB0YXhhIHJlcHJlc2VudGVkIGJ5IDEsIDIsIDMsIC4uLiBvY2N1cnJlbmNlcyBhbmQgdGhlIG9uZSB0aGF0IHdlIHdvdWxkIGV4cGVjdCBmb3IgYSBnaXZlbiBkaXN0cmlidXRpb24gb2YgY29tYmluZWQgYWdlIHJhbmdlcyAoYXMgYSBwcm94eSBmb3Igc3BlY2llcyBkdXJhdGlvbikuCgpgYGB7ciBmaWcuaGVpZ2h0PTZ9CmNvbmRpdGlvbnMgPC0gIShDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rICVpbiUgYygic3Vic3BlY2llcyIsICJpbmZyYW9yZGVyIikpICYgQ2V0YWNlYV9vY2MkYWdlX3JhbmdlPDEwCgpnZ3Bsb3QoQ2V0YWNlYV9vY2NbY29uZGl0aW9ucyxdLCBhZXMoeD1hZ2VfY29tYmluZWRfcmFuZ2UsIGZpbGw9YWNjZXB0ZWRfcmFuaykpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDEpICsgCiAgI2dlb21fcG9pbnQoKSArCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiQWdlIHJhbmdlIChNeSkiKSArCiAgI3NjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIsIG5hbWUgPSAiQ291bnQgKGxvZy1zY2FsZSkiKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSJBY2NlcHRlZCByYW5rIikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBsZWdlbmQucG9zaXRpb249ImJvdHRvbSIpICsKICBnZ3RpdGxlKCJPYnNlcnZlZCBkaXN0cmlidXRpb25zIG9mIGNvbWJpbmVkIGFnZSByYW5nZXMiKSArCiAgZmFjZXRfZ3JpZCguIH4gYWNjZXB0ZWRfcmFuaywgc2NhbGVzID0gImZyZWUiKQoKZ2dwbG90KENldGFjZWFfb2NjW2NvbmRpdGlvbnMsXSwgYWVzKHg9YWNjZXB0ZWRfbmFtZV9jb3VudCwgeT0odGFibGUoYWNjZXB0ZWRfbmFtZV9jb3VudCkvYXMubnVtZXJpYyhuYW1lcyh0YWJsZShhY2NlcHRlZF9uYW1lX2NvdW50KSkpKVthcy5mYWN0b3IoYWNjZXB0ZWRfbmFtZV9jb3VudCldLCBjb2w9YWNjZXB0ZWRfcmFuaykpICsKICBnZW9tX3BvaW50KCkgKwogIHNjYWxlX3hfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIsIG5hbWUgPSAiTnVtYmVyIG9mIG9jY3VycmVuY2VzIGJ5IGFjY2VwdGVkIG5hbWUgKGxvZy1zY2FsZSkiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZzEwIiwgbmFtZSA9ICJOdW1iZXIgb2YgY29ycmVzcG9uZGluZyBhY2NlcHRlZCBuYW1lcyAobG9nLXNjYWxlKSIpICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWU9IkFjY2VwdGVkIHJhbmsiKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCkpICsKICBnZ3RpdGxlKCJPYnNlcnZlZCBkaXN0cmlidXRpb25zIG9mIHRoZSBudW1iZXIgb2YgYWNjZXB0ZWQgbmFtZXMgd2l0aCB0aGUgc2FtZSBudW1iZXIgb2Ygb2NjdXJyZW5jZXMiKSArCiAgZmFjZXRfZ3JpZChhY2NlcHRlZF9yYW5rIH4gLiwgc2NhbGVzID0gImZyZWUiKQpgYGAKCkluIGEgUG9pc3NvbiBwcm9jZXNzIHdpdGggb2NjdXJyZW5jZSBzYW1wbGluZyByYXRlICRcb21lZ2EkIGFuZCBmb3IgYSBnaXZlbiB0aW1lIGludGVydmFsIG9mIGxlbmd0aCAkdCQsIHRoZSBwcm9iYWJpbGl0eSBvZiBvYnNlcnZpbmcgJE5fdCA9IGskIG9jY3VycmVuY2VzIGlzIGdpdmVuIGJ5IHRoZSBQb2lzc29uIGRpc3RyaWJ1dGlvbiBvZiBtZWFuIG9mIHBhcmFtZXRlciAkXG9tZWdhXHRpbWVzIHQkIDogCgokJFxtYXRoYmJ7UH0oTl90PWspID0gZV57LVxvbWVnYSB0fVxmcmFjeyhcb21lZ2EgdClea317ayF9JCQKClNvIGluIG9yZGVyIHRvIGhhdmUgdGhlIGFic29sdXRlIHByb2JhYmlsaXR5IG9mIG9ic2VydmluZyAkTl8wID0gbiQgb2NjdXJyZW5jZXMgd2UgaGF2ZSB0byBpbnRlZ3JhdGUgb3ZlciB0aGUgZnVsbCBkaXN0cmlidXRpb24gb2YgYWdlIHJhbmdlcyAkdCQsIGNhbGxlZCAkZih0KSQgOgoKJCRcbWF0aGJie1B9KE5fMCA9IG4pID0gXGludF90IFAoTl90ID0gbikgZih0KSBkdCA9IFxpbnRfdCBlXnstXG9tZWdhIHR9XGZyYWN7KFxvbWVnYSB0KV5ufXtuIX0gZih0KSBkdCQkCgpGaXJzdCwgIGFwcHJveGltYXRlIHRoaXMgZGlzdHJpYnV0aW9uIDoKCmBgYHtyfQpyYW5nZV9kZW5zaXR5IDwtIGFwcHJveGZ1bihkZW5zaXR5KENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGFjY2VwdGVkX3Jhbms9PSJzcGVjaWVzIixdJGFnZV9jb21iaW5lZF9yYW5nZVtpcy5maW5pdGUoQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF0kYWdlX2NvbWJpbmVkX3JhbmdlKV0pKQoKaGlzdChDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rPT0ic3BlY2llcyIsXSRhZ2VfY29tYmluZWRfcmFuZ2UsIHByb2JhYmlsaXR5ID0gVCwgYnJlYWtzID0gMjAsIG1haW49IkRlbnNpdHkgYXBwcm94aW1hdGlvbiBvZiB0aGUgZW1waXJpY2FsIHJhbmdlIGRpc3RyaWJ1dGlvbiIsIHhsYWIgPSAiQWdlIHJhbmdlIChNeSkiKQpsaW5lcygxOjEwMC81LCByYW5nZV9kZW5zaXR5KDE6MTAwLzUpKQpgYGAKClRoZW4gaW50ZWdyYXRlIGFuZCBwbG90IHRoZSBleHBlY3RlZCBkaXN0cmlidXRpb24gZm9yIGEgZ2l2ZW4gb21lZ2EgOgoKYGBge3J9CmV4cGVjdGVkX2Rpc3RyaWJ1dGlvbiA8LSBmdW5jdGlvbihuLCBvbWVnYSwgYWdlX2NvbWJpbmVkX3JhbmdlKXsKICByYW5nZV9kZW5zaXR5IDwtIGFwcHJveGZ1bihkZW5zaXR5KGFnZV9jb21iaW5lZF9yYW5nZVtpcy5maW5pdGUoYWdlX2NvbWJpbmVkX3JhbmdlKV0pKQogIGcgPC0gZnVuY3Rpb24odCl7ZHBvaXMobiwgb21lZ2EqdCkqcmFuZ2VfZGVuc2l0eSh0KX0KICByZXR1cm4gKGludGVncmF0ZShnLCBsb3dlciA9IDEsIHVwcGVyID0gbWF4KGFnZV9jb21iaW5lZF9yYW5nZSkpKQp9CgpvbWVnYSA8LSAwLjEKCmRlbnMgPC0gc2FwcGx5KDA6MjAsIGZ1bmN0aW9uKG4pe2V4cGVjdGVkX2Rpc3RyaWJ1dGlvbihuLCBvbWVnYSwgQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF0kYWdlX2NvbWJpbmVkX3JhbmdlKSR2YWx1ZX0pCgpwbG90KDA6MjAsIGRlbnMsIG1haW49IkV4cGVjdGVkIGRpc3RyaWJ1dGlvbiBvZiB0aGUgbnVtYmVyIG9mIGFjY2VwdGVkIG5hbWVzIHdpdGggdGhlIHNhbWUgbnVtYmVyIG9mIG9jY3VycmVuY2VzIiwgeGxhYj0iTnVtYmVyIG9mIG9jY3VycmVuY2VzIHdpdGggdGhlIHNhbWUgYWNjZXB0ZWQgbmFtZSIsIHlsYWIgPSAiUHJvcG9ydGlvbnMiLCB0eXBlID0gImIiKQpgYGAKCkZpbmFsbHksIHRyeSB0byBmaW5kIGFuICRcb21lZ2EkIHZhbHVlIHRoYXQgYXBwcm94aW1hdGVseSBmaXRzIHRoZSBmaXJzdCBwb2ludHMgKHRoZSBsZWFzdCBhZmZlY3RlZCBieSBvdmVyc2FtcGxpbmcgYmlhc2VzKSBhbmQgY2hlY2sgaWYgdGhlIG90aGVyIHBvaW50cyBmb2xsb3cgdGhlIGV4cGVjdGVkIGN1cnZlIDoKCmBgYHtyIGZpZy5oZWlnaHQ9Nn0KIyBSZWNvdW50IHRoZSBudW1iZXIgb2Ygb2NjdXJyZW5jZXMgd2l0aCB0aGUgc2FtZSBhY2NlcHRlZCBuYW1lIGFmdGVyIHRoZSBzYW1wbGluZwpDZXRhY2VhX29jY19zYW1wbGVkJGFjY2VwdGVkX25hbWVfY291bnQgPC0gc2FwcGx5KENldGFjZWFfb2NjX3NhbXBsZWQkYWNjZXB0ZWRfbmFtZSwgZnVuY3Rpb24oeCl7dGFibGUoQ2V0YWNlYV9vY2Nfc2FtcGxlZCRhY2NlcHRlZF9uYW1lKVt4XX0pCgpvbWVnYSA8LSAwLjEKYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzIDwtIENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGFjY2VwdGVkX3Jhbms9PSJzcGVjaWVzIixdJGFjY2VwdGVkX25hbWVfY291bnQKZGVucyA8LSBzYXBwbHkoMTptYXgoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzKSwgZnVuY3Rpb24obil7IGV4cGVjdGVkX2Rpc3RyaWJ1dGlvbihuLCBvbWVnYSwgQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF0kYWdlX2NvbWJpbmVkX3JhbmdlKSR2YWx1ZSB9KQphY2NlcHRlZF9uYW1lX2NvdW50X2NhdGVnb3JpZXMgPC0gdGFibGUoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzKS9hcy5udW1lcmljKG5hbWVzKHRhYmxlKGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llcykpKSAgIyBOdW1iZXIgb2YgY2F0ZWdvcmllcyB3aXRoIDEsIDIsIDMsIC4uLiBvY2N1cnJlbmNlcyBvZiB0aGUgc2FtZSBzcGVjaWVzCgojIENvbXBhcmUgdGhlIGluaXRpYWwgb2JzZXJ2ZWQgZGlzdHJpYnV0aW9uIHdpdGggdGhlIHRoZW9yZXRpY2FsIGN1cnZlCmdncGxvdChDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rPT0ic3BlY2llcyIsXSwKICAgICAgIGFlcyh4PWFjY2VwdGVkX25hbWVfY291bnQsIAogICAgICAgICAgIHk9YWNjZXB0ZWRfbmFtZV9jb3VudF9jYXRlZ29yaWVzW2FzLmZhY3RvcihhY2NlcHRlZF9uYW1lX2NvdW50KV0sIAogICAgICAgICAgIGZpbGw9YWNjZXB0ZWRfcmFuaykpICsKICBnZW9tX3BvaW50KCkgKwogIAogIGFubm90YXRlKCJsaW5lIiwgeCA9IDE6bWF4KGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llcyksIHk9IGRlbnMKICAgICptYXgoYWNjZXB0ZWRfbmFtZV9jb3VudF9jYXRlZ29yaWVzW2FzLmZhY3RvcihhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXMpXSkgL21heChkZW5zKSkrCiAgCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiTnVtYmVyIG9mIG9jY3VycmVuY2VzIGJ5IGFjY2VwdGVkIG5hbWUiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZzEwIiwgbmFtZSA9ICJOdW1iZXIgb2YgY29ycmVzcG9uZGluZyBhY2NlcHRlZCBuYW1lcyAobG9nLXNjYWxlKSIpICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWU9Ik9ic2VydmVkIGRpc3RyaWJ1dGlvbiIpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksIAogICAgICAgIHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIGdndGl0bGUoIkNvbXBhcmlzb24gYmV0d2VlbiBleHBlY3RlZCBhbmQgb2JzZXJ2ZWQgZGlzdHJpYnV0aW9ucyBvZiBudW1iZXIgb2Ygb2NjdXJyZW5jZXMiKSArCiAgZmFjZXRfZ3JpZChhY2NlcHRlZF9yYW5rIH4gLiwgc2NhbGVzID0gImZyZWUiKQoKYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzX3NhbXBsZWQgPC0gQ2V0YWNlYV9vY2Nfc2FtcGxlZFtDZXRhY2VhX29jY19zYW1wbGVkJGFjY2VwdGVkX3Jhbms9PSJzcGVjaWVzIixdJGFjY2VwdGVkX25hbWVfY291bnQKZGVuc19zYW1wbGVkIDwtIHNhcHBseSgxOm1heChhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXNfc2FtcGxlZCksIGZ1bmN0aW9uKG4pewogICAgIGV4cGVjdGVkX2Rpc3RyaWJ1dGlvbihuLCBvbWVnYSwgQ2V0YWNlYV9vY2Nfc2FtcGxlZFtDZXRhY2VhX29jY19zYW1wbGVkJGFjY2VwdGVkX3Jhbms9PSJzcGVjaWVzIixdJGFnZV9jb21iaW5lZF9yYW5nZSkkdmFsdWUKICAgIH0pCmFjY2VwdGVkX25hbWVfY291bnRfY2F0ZWdvcmllc19zYW1wbGVkIDwtIHRhYmxlKGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19zYW1wbGVkKS9hcy5udW1lcmljKG5hbWVzKHRhYmxlKGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19zYW1wbGVkKSkpICAjIE51bWJlciBvZiBjYXRlZ29yaWVzIHdpdGggMSwgMiwgMywgLi4uIG9jY3VycmVuY2VzIG9mIHRoZSBzYW1lIHNwZWNpZXMKCiMgQ29tcGFyZSB0aGUgY29ycmVjdGVkIG9ic2VydmVkIGRpc3RyaWJ1dGlvbiB3aXRoIHRoZSB0aGVvcmV0aWNhbCBjdXJ2ZQpnZ3Bsb3QoQ2V0YWNlYV9vY2Nfc2FtcGxlZFtDZXRhY2VhX29jY19zYW1wbGVkJGFjY2VwdGVkX3Jhbms9PSJzcGVjaWVzIixdLCAKICAgICAgIGFlcyh4PWFjY2VwdGVkX25hbWVfY291bnQsCiAgICAgICAgICAgeT1hY2NlcHRlZF9uYW1lX2NvdW50X2NhdGVnb3JpZXNfc2FtcGxlZFthcy5mYWN0b3IoYWNjZXB0ZWRfbmFtZV9jb3VudCldLAogICAgICAgICAgIGZpbGw9YWNjZXB0ZWRfcmFuaykpICsKICBnZW9tX3BvaW50KCkgKwogIAogIGFubm90YXRlKCJsaW5lIiwgeCA9IDE6bWF4KGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19zYW1wbGVkKSwgeT0gZGVuc19zYW1wbGVkCiAgICAqbWF4KGFjY2VwdGVkX25hbWVfY291bnRfY2F0ZWdvcmllc19zYW1wbGVkW2FzLmZhY3RvcihhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXNfc2FtcGxlZCldKSAvbWF4KGRlbnNfc2FtcGxlZCkpICsKICAKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJOdW1iZXIgb2Ygb2NjdXJyZW5jZXMgYnkgYWNjZXB0ZWQgbmFtZSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiLCBuYW1lID0gIk51bWJlciBvZiBjb3JyZXNwb25kaW5nIGFjY2VwdGVkIG5hbWVzIChsb2ctc2NhbGUpIikgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iT2JzZXJ2ZWQgZGlzdHJpYnV0aW9uIikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpKSArCiAgZ2d0aXRsZSgiQ29tcGFyaXNvbiBiZXR3ZWVuIGV4cGVjdGVkIGFuZCBvYnNlcnZlZCBkaXN0cmlidXRpb25zIG9mIG51bWJlciBvZiBvY2N1cnJlbmNlcywgYWZ0ZXIgc2FtcGxpbmciKSArCiAgZmFjZXRfZ3JpZChhY2NlcHRlZF9yYW5rIH4gLiwgc2NhbGVzID0gImZyZWUiKQpgYGAKCiRcaW1wbGllcyQgSW5pdGlhbCBvYnNlcnZhdGlvbnMgcmVhbGx5IGRvIG5vdCBmaXQgdGhlIGV4cGVjdGF0aW9ucywgKipzcGVjaWVzIHdpdGggbW9yZSB0aGFuIDUgb2NjdXJyZW5jZXMgbXVzdCByZW1haW4gdmVyeSByYXJlKiogISBCdXQgb3VyIHN1YnNhbXBsaW5nIHNlZW1zIHRvIGNvcnJlY3QgbW9zdCBvZiB0aGlzIGJpYXMuCgpIb3dldmVyLCB0aGlzIG1ldGhvZCByZXF1aXJlcyB0byBtYWtlIHNldmVyYWwgYXJiaXRyYXJ5IGNob2ljZXMgdGhhdCBtYXkgaW50cm9kdWNlIG5ldyBiaWFzZXMgc28gd2Ugd2lsbCBpbnN0ZWFkIHN1YnNhbXBsZSBhdCBvdGhlciBsZXZlbHMgKHBhbGFlb250b2xvZ2ljYWwgY29sbGVjdGlvbiwgZ2VvbG9naWNhbCBmb3JtYXRpb24pLiBJbiBlYWNoIGNhc2Ugb25seSBvbmUgb2NjdXJyZW5jZSB3aWxsIGJlIHNhbXBsZWQgZm9yIHRoZSBzaW1pbGFybHkgaWRlbnRpZmllZCwgYSBwcm9jZXNzIHdlIHdpbGwgcmVmZXIgdG8gYXMgKiphZ2dyZWdhdGluZyoqIHRoZXNlIG9jY3VycmVuY2VzIGFjY29yZGluZyB0byB0aGUgY2hvc2VuIGZhY3Rvci4KCiMjIEFnZ3JlZ2F0ZSBzaW1pbGFybHkgaWRlbnRpZmllZCBvY2N1cnJlbmNlcyBpbiBlYWNoIGNvbGxlY3Rpb24KCmBgYHtyIGZpZy5oZWlnaHQ9Nn0KZm9yIChuIGluIDU6MTApewogIEEgPC0gQ2V0YWNlYV9vY2NbYXMubG9naWNhbCh0YWJsZShDZXRhY2VhX29jYyRjb2xsZWN0aW9uX25vKVtDZXRhY2VhX29jYyRjb2xsZWN0aW9uX25vXT09biksXQogIEEkY29sbGVjdGlvbl9ubyA8LSBkcm9wbGV2ZWxzKEEkY29sbGVjdGlvbl9ubykKCiAgcCA8LSBnZ3Bsb3QoQSwgYWVzKHg9LWFnZV9tZWFuLCBmaWxsPWFjY2VwdGVkX25hbWUpKSArCiAgICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuNSwgY29sPSJibGFjayIpICsKICAgIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIlRpbWUgKE15KSIpICsKICAgIHNjYWxlX3lfY29udGludW91cyhuYW1lID0gIk51bWJlciBvZiBvY2N1cnJlbmNlcyBpbiB0aGUgY29sbGVjdGlvbiIpICsKICAgIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKwogICAgZ2d0aXRsZShwYXN0ZSgiRGlzdHJpYnV0aW9uIG9mIG9jY3VycmVuY2VzJyBtZWFuIGFnZSBmb3IgY29sbGVjdGlvbnMgd2l0aCIsIG4sICJvY2N1cnJlbmNlcyAoY29sb3JlZCBieSB0YXhhKSIpKSArCiAgICBmYWNldF9ncmlkKGNvbGxlY3Rpb25fbm8gfiAuLCBzY2FsZXM9ImZyZWUiKQogIHByaW50KHApCn0KCkEgPC0gQ2V0YWNlYV9vY2NbYXMubG9naWNhbCh0YWJsZShDZXRhY2VhX29jYyRjb2xsZWN0aW9uX25vKVtDZXRhY2VhX29jYyRjb2xsZWN0aW9uX25vXT4xMCksXQpBJGNvbGxlY3Rpb25fbm8gPC0gZHJvcGxldmVscyhBJGNvbGxlY3Rpb25fbm8pCgpnZ3Bsb3QoQSwgYWVzKHg9LWFnZV9tZWFuLCBmaWxsPWFjY2VwdGVkX25hbWUpKSArCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjUsIGNvbD0iYmxhY2siKSArCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiVGltZSAoTXkpIikgKwogIHNjYWxlX3lfY29udGludW91cyhuYW1lID0gIk51bWJlciBvZiBvY2N1cnJlbmNlcyBpbiB0aGUgY29sbGVjdGlvbiIpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArCiAgZ2d0aXRsZSgiRGlzdHJpYnV0aW9uIG9mIG9jY3VycmVuY2VzJyBtZWFuIGFnZSBmb3IgY29sbGVjdGlvbnMgd2l0aCA+MTAgb2NjdXJyZW5jZXMiKSArCiAgZmFjZXRfZ3JpZChjb2xsZWN0aW9uX25vIH4gLiwgc2NhbGVzPSJmcmVlIikKYGBgCgokXHRvJCBFYWNoIGNvbGxlY3Rpb24gY29ycmVzcG9uZHMgdG8gYSB1bmlxdWUgdGltZSBpbnRlcnZhbCAoaW5mZXJyZWQgZnJvbSB0aGUgdW5pcXVlIGFnZSBtZWFuKS4KCkluIG9yZGVyIHRvIHJlZHVjZSB0aGUgYWJ1bmRhbmNlIGJpYXMsIHdlIG1heSBrZWVwIG9ubHkgb25lIG9jY3VycmVuY2UgZm9yIGVhY2ggY29sbGVjdGlvbiA6CgpgYGB7cn0KQ2V0YWNlYV9vY2NfYWdncmVnIDwtIGMoKQoKIyBCcm93c2UgYWxsIGNvbGxlY3Rpb25zCmNvbGxlY3Rpb25zIDwtIGxldmVscyhkcm9wbGV2ZWxzKENldGFjZWFfb2NjJGNvbGxlY3Rpb25fbm8pKQpmb3IgKGNvbGwgaW4gY29sbGVjdGlvbnMpewogIENldGFjZWFfb2NjX2NvbGwgPC0gQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkY29sbGVjdGlvbl9ubz09Y29sbCxdCiAgCiAgIyBCcm93c2UgYWxsIGFjY2VwdGVkIG5hbWVzIGluIGVhY2ggY29sbGVjdGlvbiAmIHNhbXBsZSBvbmx5IDEgb2NjdXJyZW5jZQogIHRheGEgPC0gbGV2ZWxzKGRyb3BsZXZlbHMoQ2V0YWNlYV9vY2NfY29sbCRhY2NlcHRlZF9uYW1lKSkKICBmb3IgKG5hbWUgaW4gdGF4YSl7CiAgICBDZXRhY2VhX29jY19hZ2dyZWcgPC0gcmJpbmQoQ2V0YWNlYV9vY2NfYWdncmVnLCBzYW1wbGVfbihDZXRhY2VhX29jY19jb2xsW0NldGFjZWFfb2NjX2NvbGwkYWNjZXB0ZWRfbmFtZT09bmFtZSxdLCBzaXplID0gMSkpCiAgfQp9CgpkYXRhLmZyYW1lKENldGFjZWFfb2NjID0gYyhkaW0oQ2V0YWNlYV9vY2MpWzFdLAogICAgICAgICAgICAgICAgICAgICAgICAgICBkaW0oQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayA9PSJzcGVjaWVzIixdKVsxXSksCiAgICAgICAgICAgQ2V0YWNlYV9vY2NfYWdncmVnID0gYyhkaW0oQ2V0YWNlYV9vY2NfYWdncmVnKVsxXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpbShDZXRhY2VhX29jY19hZ2dyZWdbQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX3JhbmsgPT0ic3BlY2llcyIsXSlbMV0pLAogICAgICAgICAgIHJlbW92ZWQgPSBjKGRpbShDZXRhY2VhX29jYylbMV0tZGltKENldGFjZWFfb2NjX2FnZ3JlZylbMV0sCiAgICAgICAgICAgICAgICAgICAgICAgZGltKENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGFjY2VwdGVkX3JhbmsgPT0ic3BlY2llcyIsXSlbMV0tZGltKENldGFjZWFfb2NjX2FnZ3JlZ1tDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfcmFuayA9PSJzcGVjaWVzIixdKVsxXSksCiAgICAgICAgICAgcm93Lm5hbWVzID0gYygiTnVtYmVyIG9mIG9jY3VycmVuY2VzIiwgIk51bWJlciBvZiBvY2N1cnJlbmNlcyAoc3BlY2llcyBvbmx5KSIpKQpgYGAKCiRcdG8kIE5vdCBlbm91Z2ggb2NjdXJyZW5jZXMgYXJlIHJlbW92ZWQgdG8gbWFrZSBhIHN1ZmZpY2llbnQgZGlmZmVyZW5jZS4gSWYgd2UgbG9vayBhdCB0aGUgY29sbGVjdGlvbiB3aXRoIHRoZSBoaWdoZXN0IG51bWJlciBvZiBvY2N1cnJlbmNlcyA6CgpgYGB7cn0KY29sbGVjdGlvbl9tYXhfb2NjdXJyZW5jZXMgPC0gbWF4KHRhYmxlKENldGFjZWFfb2NjJGNvbGxlY3Rpb25fbm8pW0NldGFjZWFfb2NjJGNvbGxlY3Rpb25fbm9dKQpjb2xsZWN0aW9uX21heF9ubyA8LSBuYW1lcyh0YWJsZShDZXRhY2VhX29jYyRjb2xsZWN0aW9uX25vKVtDZXRhY2VhX29jYyRjb2xsZWN0aW9uX25vXVt0YWJsZShDZXRhY2VhX29jYyRjb2xsZWN0aW9uX25vKVtDZXRhY2VhX29jYyRjb2xsZWN0aW9uX25vXT09Y29sbGVjdGlvbl9tYXhfb2NjdXJyZW5jZXNdWzFdKQoKdGFibGUoZHJvcGxldmVscyhDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRjb2xsZWN0aW9uX25vPT1jb2xsZWN0aW9uX21heF9ubyxdJGFjY2VwdGVkX25hbWUpKQpgYGAKCiRcdG8kIFRoZXJlIGFyZSB2ZXJ5IGZldyByZWR1bmRhbmNpZXMgYW1vbmcgdGhlIGFjY2VwdGVkIG5hbWVzIGluIGNvbGxlY3Rpb25zIHNvIGFnZ3JlZ2F0aW5nIHRob3NlIHdvbid0IHJlZHVjZSB0aGUgYWJ1bmRhbmNlIGJpYXMuCgpJbnN0ZWFkLCB3ZSBtYXkgdHJ5IHRvICoqYWdncmVnYXRlIG9jY3VycmVuY2VzIHdpdGggdGhlIHNhbWUgYWNjZXB0ZWQgbmFtZSBhdCB0aGUgbGV2ZWwgb2YgdGhlIGdlb2xvZ2ljYWwgZm9ybWF0aW9uKiogKGllIHN1YnNhbXBsZSBvbmx5IG9uZSBmb3IgZWFjaCkuCgojIyBBZ2dyZWdhdGUgc2ltaWxhcmx5IGlkZW50aWZpZWQgb2NjdXJyZW5jZXMgaW4gZWFjaCBmb3JtYXRpb24KCmBgYHtyIGZpZy5oZWlnaHQ9OH0KQ2V0YWNlYV9vY2Nfc3BlY2llcyA8LSBDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rPT0ic3BlY2llcyIsXQoKIyBCcm93c2UgYWxsIG51bWJlcnMgb2Ygb2NjdXJyZW5jZXMgYnkgZm9ybWF0aW9uCmZvcm1hdGlvbl9vY2N1cnJlbmNlc19uYiA8LSBhcy5udW1lcmljKG5hbWVzKHRhYmxlKHRhYmxlKGRyb3BsZXZlbHMoQ2V0YWNlYV9vY2Nfc3BlY2llcyRmb3JtYXRpb24pKSkpKQoKZm9yIChuIGluIGxpc3QoYyg0LCA3KSwgYyg4LCAxNSksIGMoMTYsIDEyNCkpKXsKICBBIDwtIENldGFjZWFfb2NjX3NwZWNpZXNbYXMubG9naWNhbCh0YWJsZShDZXRhY2VhX29jY19zcGVjaWVzJGZvcm1hdGlvbilbQ2V0YWNlYV9vY2Nfc3BlY2llcyRmb3JtYXRpb25dPj1uWzFdKQogICAgICAgICAgICAgICAgICAgICAgICAgICAmIGFzLmxvZ2ljYWwodGFibGUoQ2V0YWNlYV9vY2Nfc3BlY2llcyRmb3JtYXRpb24pW0NldGFjZWFfb2NjX3NwZWNpZXMkZm9ybWF0aW9uXTw9blsyXSksXQogIEEkZm9ybWF0aW9uIDwtIGRyb3BsZXZlbHMoQSRmb3JtYXRpb24pCgogIHAgPC0gZ2dwbG90KEEsIGFlcyh4PS1hZ2VfbWVhbiwgZmlsbD1hY2NlcHRlZF9uYW1lKSkgKwogICAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjUsIGNvbD0iYmxhY2siKSArCiAgICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJUaW1lIChNeSkiKSArCiAgICBzY2FsZV95X2NvbnRpbnVvdXMobmFtZSA9ICJOdW1iZXIgb2Ygb2NjdXJyZW5jZXMgaW4gdGhlIGZvcm1hdGlvbiIpICsKICAgIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iQWNjZXB0ZWQgbmFtZSIpICsKICAgIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKwogICAgZ2d0aXRsZShwYXN0ZSgiRGlzdHJpYnV0aW9uIG9mIG9jY3VycmVuY2VzJyBtZWFuIGFnZSBmb3IgZm9ybWF0aW9ucyB3aXRoIiwgblsxXSwgIi0iLCBuWzJdLCAib2NjdXJyZW5jZXMgKGNvbG9yZWQgYnkgc3BlY2llcykiKSkgKwogICAgZmFjZXRfZ3JpZChmb3JtYXRpb24gfiAuLCBzY2FsZXM9ImZyZWUiKQogIHByaW50KHApCn0KCm1heF9zcGVjaWVzX2J5X2Zvcm1hdGlvbiA8LSBtYXgodGFibGUoQ2V0YWNlYV9vY2Nfc3BlY2llcyRmb3JtYXRpb24pKQpBIDwtIENldGFjZWFfb2NjX3NwZWNpZXNbYXMubG9naWNhbCh0YWJsZShDZXRhY2VhX29jY19zcGVjaWVzJGZvcm1hdGlvbilbQ2V0YWNlYV9vY2Nfc3BlY2llcyRmb3JtYXRpb25dPT1tYXhfc3BlY2llc19ieV9mb3JtYXRpb24pLF0KQSRmb3JtYXRpb24gPC0gZHJvcGxldmVscyhBJGZvcm1hdGlvbikKCmdncGxvdChBLCBhZXMoeD0tYWdlX21lYW4sIGZpbGw9cmVvcmRlcihhY2NlcHRlZF9uYW1lLCAtYWdlX21lYW4pKSkgKwogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMC41LCBjb2w9ImJsYWNrIikgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIlRpbWUgKE15KSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobmFtZSA9ICJOdW1iZXIgb2Ygb2NjdXJyZW5jZXMgaW4gdGhlIGZvcm1hdGlvbiIpICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWU9IkFjY2VwdGVkIG5hbWUiKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKwogIGdndGl0bGUocGFzdGUoIkRpc3RyaWJ1dGlvbiBvZiBvY2N1cnJlbmNlcycgbWVhbiBhZ2UgZm9yIiwgbWF4X3NwZWNpZXNfYnlfZm9ybWF0aW9uLCAib2NjdXJyZW5jZXMgd2l0aG91dCBpbmRpY2F0ZWQgZm9ybWF0aW9uIChjb2xvcmVkIGJ5IHNwZWNpZXMpIikpICsKICBmYWNldF9ncmlkKGZvcm1hdGlvbiB+IC4pCmBgYAoKJFx0byQgRm9yIG1vc3QgZm9ybWF0aW9ucyBlYWNoIHNwZWNpZXMgc2VlbXMgdG8gYmUgcmVzdHJpY3RlZCB0byBvbmx5IG9uZSBhZ2UsIHNvIGFzIGV4cGVjdGVkIHdlIGFyZSBub3QgbG9vc2luZyB0b28gbXVjaCBpbmZvcm1hdGlvbiB3aGVuIGFnZ3JlZ2F0aW5nIHRoZW0gdG8gYSBzaW5nbGUgb2NjdXJyZW5jZS4KCmBgYHtyfQpDZXRhY2VhX29jY19hZ2dyZWcgPC0gYygpCgojIEJyb3dzZSBhbGwgZm9ybWF0aW9ucwpmb3JtYXRpb25zIDwtIGxldmVscyhkcm9wbGV2ZWxzKENldGFjZWFfb2NjJGZvcm1hdGlvbikpCmZvciAoZm9ybSBpbiBmb3JtYXRpb25zKXsKICBDZXRhY2VhX29jY19mb3JtIDwtIENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGZvcm1hdGlvbj09Zm9ybSxdCiAgCiAgIyBCcm93c2UgYWxsIGFjY2VwdGVkIG5hbWVzIGluIGVhY2ggZm9ybWF0aW9uICYgc2FtcGxlIG9ubHkgMSBvY2N1cnJlbmNlCiAgdGF4YSA8LSBsZXZlbHMoZHJvcGxldmVscyhDZXRhY2VhX29jY19mb3JtJGFjY2VwdGVkX25hbWUpKQogIGZvciAobmFtZSBpbiB0YXhhKXsKICAgIENldGFjZWFfb2NjX2FnZ3JlZyA8LSByYmluZChDZXRhY2VhX29jY19hZ2dyZWcsIHNhbXBsZV9uKENldGFjZWFfb2NjX2Zvcm1bQ2V0YWNlYV9vY2NfZm9ybSRhY2NlcHRlZF9uYW1lPT1uYW1lLF0sIHNpemUgPSAxKSkKICB9Cn0KCmRhdGEuZnJhbWUoQ2V0YWNlYV9vY2MgPSBjKGRpbShDZXRhY2VhX29jYylbMV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpbShDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rID09InNwZWNpZXMiLF0pWzFdKSwKICAgICAgICAgICBDZXRhY2VhX29jY19hZ2dyZWcgPSBjKGRpbShDZXRhY2VhX29jY19hZ2dyZWcpWzFdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGltKENldGFjZWFfb2NjX2FnZ3JlZ1tDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfcmFuayA9PSJzcGVjaWVzIixdKVsxXSksCiAgICAgICAgICAgcmVtb3ZlZCA9IGMoZGltKENldGFjZWFfb2NjKVsxXS1kaW0oQ2V0YWNlYV9vY2NfYWdncmVnKVsxXSwKICAgICAgICAgICAgICAgICAgICAgICBkaW0oQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayA9PSJzcGVjaWVzIixdKVsxXS1kaW0oQ2V0YWNlYV9vY2NfYWdncmVnW0NldGFjZWFfb2NjX2FnZ3JlZyRhY2NlcHRlZF9yYW5rID09InNwZWNpZXMiLF0pWzFdKSwKICAgICAgICAgICByb3cubmFtZXMgPSBjKCJOdW1iZXIgb2Ygb2NjdXJyZW5jZXMiLCAiTnVtYmVyIG9mIG9jY3VycmVuY2VzIChzcGVjaWVzIG9ubHkpIikpCmBgYAoKJFx0byQgSW4gdGhhdCBjYXNlIHRoZSBzdWItc2FtcGxpbmcgaXMgYmlnIGVub3VnaCB0byBob3BlIGNvcnJlY3Rpbmcgb3VyIGJpYXMuCgpgYGB7ciBmaWcuaGVpZ2h0PTd9CiMgUmVjb3VudCB0aGUgbnVtYmVyIG9mIG9jY3VycmVuY2VzIHdpdGggdGhlIHNhbWUgYWNjZXB0ZWQgbmFtZSBhZnRlciB0aGUgYWdncmVnYXRpb24KQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX25hbWVfY291bnQgPC0gc2FwcGx5KENldGFjZWFfb2NjX2FnZ3JlZyRhY2NlcHRlZF9uYW1lLCBmdW5jdGlvbih4KXt0YWJsZShDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfbmFtZSlbeF19KQoKb21lZ2EgPC0gMC4xCmFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llcyA8LSBDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rPT0ic3BlY2llcyIsXSRhY2NlcHRlZF9uYW1lX2NvdW50CmRlbnMgPC0gc2FwcGx5KDE6bWF4KGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llcyksIGZ1bmN0aW9uKG4peyBleHBlY3RlZF9kaXN0cmlidXRpb24obiwgb21lZ2EsIENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGFjY2VwdGVkX3Jhbms9PSJzcGVjaWVzIixdJGFnZV9jb21iaW5lZF9yYW5nZSkkdmFsdWUgfSkKYWNjZXB0ZWRfbmFtZV9jb3VudF9jYXRlZ29yaWVzIDwtIHRhYmxlKGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llcykvYXMubnVtZXJpYyhuYW1lcyh0YWJsZShhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXMpKSkgICMgTnVtYmVyIG9mIGNhdGVnb3JpZXMgd2l0aCAxLCAyLCAzLCAuLi4gb2NjdXJyZW5jZXMgb2YgdGhlIHNhbWUgc3BlY2llcwoKIyBDb21wYXJlIHRoZSBpbml0aWFsIG9ic2VydmVkIGRpc3RyaWJ1dGlvbiB3aXRoIHRoZSB0aGVvcmV0aWNhbCBjdXJ2ZQpnZ3Bsb3QoQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF0sIAogICAgICAgYWVzKHg9YWNjZXB0ZWRfbmFtZV9jb3VudCwgCiAgICAgICAgICAgeT1hY2NlcHRlZF9uYW1lX2NvdW50X2NhdGVnb3JpZXNbYXMuZmFjdG9yKGFjY2VwdGVkX25hbWVfY291bnQpXSwgCiAgICAgICAgICAgZmlsbD1hY2NlcHRlZF9yYW5rKSkgKwogIGdlb21fcG9pbnQoKSArCiAgCiAgYW5ub3RhdGUoImxpbmUiLCB4ID0gMTptYXgoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzKSwgeT0gZGVucwogICAgKm1heCgodGFibGUoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzKS9hcy5udW1lcmljKG5hbWVzKHRhYmxlKGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llcykpKSlbYXMuZmFjdG9yKGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llcyldKSAvbWF4KGRlbnMpKSsKICAKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJOdW1iZXIgb2Ygb2NjdXJyZW5jZXMgYnkgYWNjZXB0ZWQgbmFtZSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMTAiLCBuYW1lID0gIk51bWJlciBvZiBjb3JyZXNwb25kaW5nIGFjY2VwdGVkIG5hbWVzIChsb2ctc2NhbGUpIikgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iT2JzZXJ2ZWQgZGlzdHJpYnV0aW9uIikgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpKSArCiAgZ2d0aXRsZSgiQ29tcGFyaXNvbiBiZXR3ZWVuIGV4cGVjdGVkIGFuZCBvYnNlcnZlZCBkaXN0cmlidXRpb25zIG9mIG51bWJlciBvZiBvY2N1cnJlbmNlcyIpICsKICBmYWNldF9ncmlkKGFjY2VwdGVkX3JhbmsgfiAuLCBzY2FsZXMgPSAiZnJlZSIpCgphY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXNfYWdncmVnIDwtIENldGFjZWFfb2NjX2FnZ3JlZ1tDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF0kYWNjZXB0ZWRfbmFtZV9jb3VudApkZW5zX2FnZ3JlZyA8LSBzYXBwbHkoMTptYXgoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzX2FnZ3JlZyksIGZ1bmN0aW9uKG4pewogICAgIGV4cGVjdGVkX2Rpc3RyaWJ1dGlvbihuLCBvbWVnYSwgQ2V0YWNlYV9vY2NfYWdncmVnW0NldGFjZWFfb2NjX2FnZ3JlZyRhY2NlcHRlZF9yYW5rPT0ic3BlY2llcyIsXSRhZ2VfY29tYmluZWRfcmFuZ2UpJHZhbHVlCiAgICB9KQphY2NlcHRlZF9uYW1lX2NvdW50X2NhdGVnb3JpZXNfYWdncmVnIDwtIHRhYmxlKGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19hZ2dyZWcpL2FzLm51bWVyaWMobmFtZXModGFibGUoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzX2FnZ3JlZykpKSAgIyBOdW1iZXIgb2YgY2F0ZWdvcmllcyB3aXRoIDEsIDIsIDMsIC4uLiBvY2N1cnJlbmNlcyBvZiB0aGUgc2FtZSBzcGVjaWVzCgojIENvbXBhcmUgdGhlIGNvcnJlY3RlZCBvYnNlcnZlZCBkaXN0cmlidXRpb24gd2l0aCB0aGUgdGhlb3JldGljYWwgY3VydmUKZ2dwbG90KENldGFjZWFfb2NjX2FnZ3JlZ1tDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF0sIAogICAgICAgYWVzKHg9YWNjZXB0ZWRfbmFtZV9jb3VudCwKICAgICAgICAgICB5PWFjY2VwdGVkX25hbWVfY291bnRfY2F0ZWdvcmllc19hZ2dyZWdbYXMuZmFjdG9yKGFjY2VwdGVkX25hbWVfY291bnQpXSwgCiAgICAgICAgICAgZmlsbD1hY2NlcHRlZF9yYW5rKSkgKwogIGdlb21fcG9pbnQoKSArCiAgCiAgYW5ub3RhdGUoImxpbmUiLCB4ID0gMTptYXgoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzX2FnZ3JlZyksIHk9IGRlbnNfYWdncmVnCiAgICAqbWF4KCh0YWJsZShhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXNfYWdncmVnKS9hcy5udW1lcmljKG5hbWVzKHRhYmxlKGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19hZ2dyZWcpKSkpW2FzLmZhY3RvcihhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXNfYWdncmVnKV0pIC9tYXgoZGVuc19hZ2dyZWcpKSArCiAgCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiTnVtYmVyIG9mIG9jY3VycmVuY2VzIGJ5IGFjY2VwdGVkIG5hbWUiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZzEwIiwgbmFtZSA9ICJOdW1iZXIgb2YgY29ycmVzcG9uZGluZyBhY2NlcHRlZCBuYW1lcyAobG9nLXNjYWxlKSIpICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWU9Ik9ic2VydmVkIGRpc3RyaWJ1dGlvbiIpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksIAogICAgICAgIHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIGdndGl0bGUoIkNvbXBhcmlzb24gYmV0d2VlbiBleHBlY3RlZCBhbmQgb2JzZXJ2ZWQgZGlzdHJpYnV0aW9ucyBvZiBudW1iZXIgb2Ygb2NjdXJyZW5jZXMsIGFmdGVyIGFnZ3JlZ2F0aW5nIGluIGZvcm1hdGlvbnMiKSArCiAgZmFjZXRfZ3JpZChhY2NlcHRlZF9yYW5rIH4gLiwgc2NhbGVzID0gImZyZWUiKQoKYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzX2FnZ3JlZyA8LSBDZXRhY2VhX29jY19hZ2dyZWdbQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX3Jhbms9PSJzcGVjaWVzIixdJGFjY2VwdGVkX25hbWVfY291bnQKZGVuc19hZ2dyZWcgPC0gc2FwcGx5KDE6bWF4KGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19hZ2dyZWcpLCBmdW5jdGlvbihuKXsKICAgICBleHBlY3RlZF9kaXN0cmlidXRpb24obiwgb21lZ2EsIENldGFjZWFfb2NjX2FnZ3JlZ1tDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF0kYWdlX2NvbWJpbmVkX3JhbmdlKSR2YWx1ZQogICAgfSkKYWNjZXB0ZWRfbmFtZV9jb3VudF9jYXRlZ29yaWVzX2FnZ3JlZyA8LSB0YWJsZShhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXNfYWdncmVnKS9hcy5udW1lcmljKG5hbWVzKHRhYmxlKGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19hZ2dyZWcpKSkgICMgTnVtYmVyIG9mIGNhdGVnb3JpZXMgd2l0aCAxLCAyLCAzLCAuLi4gb2NjdXJyZW5jZXMgb2YgdGhlIHNhbWUgc3BlY2llcwpgYGAKCiRcdG8kIFRoZSBiaWFzIGNhbiBiZSBjb3JyaWRlcmVkIGFzIGNvbXBsZXRlbHkgY29ycmVjdGVkLgoKYGBge3IgZmlnLmhlaWdodD02fQpjb25kaXRpb25zIDwtIENldGFjZWFfb2NjJGFjY2VwdGVkX3JhbmsgPT0ic3BlY2llcyIKCnAxIDwtIGdncGxvdChDZXRhY2VhX29jY1tjb25kaXRpb25zLF0sIGFlcyh4PS1hZ2VfcnVuaWYpKSArCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjUsIGFscGhhPTAuNSwgZmlsbD1OQSwgY29sPSJyZWQiKSArCiAgeGxpbSgtbWF4KENldGFjZWFfb2NjW2NvbmRpdGlvbnMsXSRhZ2VfcnVuaWYpLTEsIDEpICsKICB5bGltKDAsIDcwKSArCiAgdGhlbWVfdm9pZCgpCgpwMiA8LSBnZ3Bsb3QoQ2V0YWNlYV9vY2Nfc2FtcGxlZCwgYWVzKHg9LWFnZV9ydW5pZikpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuNSwgYWxwaGE9MC41LCBmaWxsPSJibHVlIikgKwogIHhsaW0oLW1heChDZXRhY2VhX29jY1tjb25kaXRpb25zLF0kYWdlX3J1bmlmKS0xLCAxKSArCiAgeWxpbSgwLCA3MCkgKwogIHRoZW1lX3ZvaWQoKQoKcDMgPC0gZ2dwbG90KENldGFjZWFfb2NjX2FnZ3JlZ1tDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfcmFuayA9PSJzcGVjaWVzIixdLCBhZXMoeD0tYWdlX3J1bmlmKSkgKwogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMC41LCBhbHBoYT0wLjUsIGZpbGw9ImdyZWVuIikgKwogIHhsaW0oLW1heChDZXRhY2VhX29jY1tjb25kaXRpb25zLF0kYWdlX3J1bmlmKS0xLCAxKSArCiAgeWxpbSgwLCA3MCkgKwogIHRoZW1lX3ZvaWQoKQoKcDEgKyBhbm5vdGF0aW9uX2N1c3RvbShnZ3Bsb3RHcm9iKHAyKSkgKyBnZ3RpdGxlKCJJbml0aWFsIG9jY3VycmVuY2VzIGRpc3RyaWJ1dGlvbiAocmVkKSBhbmQgY29tcGFyaXNvbiBhZnRlciBzdWItc2FtcGxpbmcgKGJsdWUpIikKCnAxICsgYW5ub3RhdGlvbl9jdXN0b20oZ2dwbG90R3JvYihwMykpICsgZ2d0aXRsZSgiSW5pdGlhbCBvY2N1cnJlbmNlcyBkaXN0cmlidXRpb24gKHJlZCkgYW5kIGNvbXBhcmlzb24gYWZ0ZXIgYWdncmVnYXRpbmcgaW4gZm9ybWF0aW9ucyAoZ3JlZW4pIikKCnAxICsgYW5ub3RhdGlvbl9jdXN0b20oZ2dwbG90R3JvYihwMikpICsgYW5ub3RhdGlvbl9jdXN0b20oZ2dwbG90R3JvYihwMykpICsgZ2d0aXRsZSgiSW5pdGlhbCBvY2N1cnJlbmNlcyBkaXN0cmlidXRpb24gKHJlZCkgYW5kIGNvbXBhcmlzb24gYWZ0ZXIgc3ViLXNhbXBsaW5nIChibHVlKSBvciBhZ2dyZWdhdGluZyBpbiBmb3JtYXRpb25zIChncmVlbikiKQpgYGAKCiRcdG8kIENvbXBhcmluZyB3aXRoIHRoZSBpbml0aWFsIG9jY3VycmVuY2VzIGRpc3RyaWJ1dGlvbiBhbmQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uIGFmdGVyIG91ciBmaXJzdCBzdWItc2FtcGxpbmcgaXQgYXBwZWFycyB0aGF0IGJvdGggbWV0aG9kcyBsZWFkIHRvIHZlcnkgc2ltaWxhciBkaXN0cmlidXRpb25zLiBUaGlzIGNvbmZvcnRzIHVzIGFib3V0IHRoZSByb2J1c3RuZXNzIG9mIHRob3NlIGFwcHJvYWNoZXMuCgpIb3dldmVyLCB3ZSBoYXZlIHRvIHRha2UgaW50byBhY2NvdW50IHRoZSBvY2N1cnJlbmNlcyB0aGF0IGRvIG5vdCBoYXZlIGFueSBpbmRpY2F0ZWQgZ2VvbG9naWNhbCBmb3JtYXRpb24gdG8gc3Vic2FtcGxlIHRoZW0gc2VwYXJhdGVseS4gVG8gYXBwcm94aW1hdGUgZ2VvbG9naWNhbCBmb3JtYXRpb24gd2UgY2hvc2UgdG8gcHJvY2VlZCB0byB0aGUgYWdncmVnYXRpb24gYmFzZWQgb24gdGhlIGNvbWJpbmF0aW9uIG9mIHRoZSBjb3VudHJ5IGFuZCB0aGUgZWFybHkgc3RyYXRpZ3JhcGhpYyBpbnRlcnZhbC4KCiMjIEFnZ3JlZ2F0ZSBvY2N1cnJlbmNlcyB3aXRob3V0IGZvcm1hdGlvbiBieSBjb3VudHJ5ICsgZWFybHkgaW50ZXJ2YWwKCmBgYHtyfQpDZXRhY2VhX29jY19hZ2dyZWcgPC0gYygpCgojIEJyb3dzZSBhbGwgY291bnRyaWVzCmNvdW50cmllcyA8LSBsZXZlbHMoZHJvcGxldmVscyhDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRmb3JtYXRpb249PSIiLF0kY2MpKQpmb3IgKGNvdW50cnkgaW4gY291bnRyaWVzKXsKICBDZXRhY2VhX29jY19jYyA8LSBDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRmb3JtYXRpb249PSIiICYgQ2V0YWNlYV9vY2MkY2M9PWNvdW50cnksXQogIAogICMgQnJvd3NlIGFsbCBlYXJseSBzdHJhdGlncmFwaGljIGludGVydmFscwogIGVhcmx5X2ludGVydmFscyA8LSBsZXZlbHMoZHJvcGxldmVscyhDZXRhY2VhX29jY19jYyRlYXJseV9pbnRlcnZhbCkpCiAgZm9yIChlaSBpbiBlYXJseV9pbnRlcnZhbHMpewogICAgQ2V0YWNlYV9vY2NfY2NfZWkgPC0gQ2V0YWNlYV9vY2NfY2NbQ2V0YWNlYV9vY2NfY2MkZWFybHlfaW50ZXJ2YWw9PWVpLF0KICAgIAogICAgIyBCcm93c2UgYWxsIGFjY2VwdGVkIG5hbWVzIGluIGVhY2ggY291bnRyeSAmIHNhbXBsZSBvbmx5IDEgb2NjdXJyZW5jZQogICAgdGF4YSA8LSBsZXZlbHMoZHJvcGxldmVscyhDZXRhY2VhX29jY19jY19laSRhY2NlcHRlZF9uYW1lKSkKICAgIGZvciAobmFtZSBpbiB0YXhhKXsKICAgICAgQ2V0YWNlYV9vY2NfYWdncmVnIDwtIHJiaW5kKENldGFjZWFfb2NjX2FnZ3JlZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNhbXBsZV9uKENldGFjZWFfb2NjX2NjX2VpW0NldGFjZWFfb2NjX2NjX2VpJGFjY2VwdGVkX25hbWU9PW5hbWUsXSwgc2l6ZSA9IDEpKQogICAgfQogIH0KfQoKIyBCcm93c2UgYWxsIGZvcm1hdGlvbnMKZm9ybWF0aW9ucyA8LSBsZXZlbHMoZHJvcGxldmVscyhDZXRhY2VhX29jYyRmb3JtYXRpb24pKQpmb3IgKGZvcm0gaW4gZm9ybWF0aW9uc1std2hpY2goZm9ybWF0aW9ucz09IiIpXSl7CiAgQ2V0YWNlYV9vY2NfZm9ybSA8LSBDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRmb3JtYXRpb249PWZvcm0sXQogIAogICMgQnJvd3NlIGFsbCBhY2NlcHRlZCBuYW1lcyBpbiBlYWNoIGZvcm1hdGlvbiAmIHNhbXBsZSBvbmx5IDEgb2NjdXJyZW5jZQogIHRheGEgPC0gbGV2ZWxzKGRyb3BsZXZlbHMoQ2V0YWNlYV9vY2NfZm9ybSRhY2NlcHRlZF9uYW1lKSkKICBmb3IgKG5hbWUgaW4gdGF4YSl7CiAgICBDZXRhY2VhX29jY19hZ2dyZWcgPC0gcmJpbmQoQ2V0YWNlYV9vY2NfYWdncmVnLCBzYW1wbGVfbihDZXRhY2VhX29jY19mb3JtW0NldGFjZWFfb2NjX2Zvcm0kYWNjZXB0ZWRfbmFtZT09bmFtZSxdLCBzaXplID0gMSkpCiAgfQp9CgpkYXRhLmZyYW1lKENldGFjZWFfb2NjID0gYyhkaW0oQ2V0YWNlYV9vY2MpWzFdLAogICAgICAgICAgICAgICAgICAgICAgICAgICBkaW0oQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayA9PSJzcGVjaWVzIixdKVsxXSksCiAgICAgICAgICAgQ2V0YWNlYV9vY2NfYWdncmVnID0gYyhkaW0oQ2V0YWNlYV9vY2NfYWdncmVnKVsxXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpbShDZXRhY2VhX29jY19hZ2dyZWdbQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX3JhbmsgPT0ic3BlY2llcyIsXSlbMV0pLAogICAgICAgICAgIHJlbW92ZWQgPSBjKGRpbShDZXRhY2VhX29jYylbMV0tZGltKENldGFjZWFfb2NjX2FnZ3JlZylbMV0sCiAgICAgICAgICAgICAgICAgICAgICAgZGltKENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGFjY2VwdGVkX3JhbmsgPT0ic3BlY2llcyIsXSlbMV0tZGltKENldGFjZWFfb2NjX2FnZ3JlZ1tDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfcmFuayA9PSJzcGVjaWVzIixdKVsxXSksCiAgICAgICAgICAgcm93Lm5hbWVzID0gYygiTnVtYmVyIG9mIG9jY3VycmVuY2VzIiwgIk51bWJlciBvZiBvY2N1cnJlbmNlcyAoc3BlY2llcyBvbmx5KSIpKQpgYGAKCk1vcmUgb2NjdXJyZW5jZXMgcmVtYWluIGFmdGVyIGFnZ3JlZ2F0aW5nIHdpdGggdGhpcyBuZXcgbWV0aG9kLiBMZXQncyBjb21wYXJlIGFnYWluIHdpdGggdGhlIHRoZW9yZXRpY2FsIGRpc3RyaWJ1dGlvbiA6CgpgYGB7ciBmaWcuaGVpZ2h0PTd9CiMgUmVjb3VudCB0aGUgbnVtYmVyIG9mIG9jY3VycmVuY2VzIHdpdGggdGhlIHNhbWUgYWNjZXB0ZWQgbmFtZSBhZnRlciB0aGUgYWdncmVnYXRpb24KQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX25hbWVfY291bnQgPC0gc2FwcGx5KENldGFjZWFfb2NjX2FnZ3JlZyRhY2NlcHRlZF9uYW1lLCBmdW5jdGlvbih4KXt0YWJsZShDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfbmFtZSlbeF19KQoKb21lZ2EgPC0gMC4xNQphY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXMgPC0gQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF0kYWNjZXB0ZWRfbmFtZV9jb3VudApkZW5zIDwtIHNhcHBseSgxOm1heChhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXMpLCBmdW5jdGlvbihuKXsgZXhwZWN0ZWRfZGlzdHJpYnV0aW9uKG4sIG9tZWdhLCBDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rPT0ic3BlY2llcyIsXSRhZ2VfY29tYmluZWRfcmFuZ2UpJHZhbHVlIH0pCmFjY2VwdGVkX25hbWVfY291bnRfY2F0ZWdvcmllcyA8LSB0YWJsZShhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXMpL2FzLm51bWVyaWMobmFtZXModGFibGUoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzKSkpICAjIE51bWJlciBvZiBjYXRlZ29yaWVzIHdpdGggMSwgMiwgMywgLi4uIG9jY3VycmVuY2VzIG9mIHRoZSBzYW1lIHNwZWNpZXMKCiMgQ29tcGFyZSB0aGUgaW5pdGlhbCBvYnNlcnZlZCBkaXN0cmlidXRpb24gd2l0aCB0aGUgdGhlb3JldGljYWwgY3VydmUKZ2dwbG90KENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGFjY2VwdGVkX3Jhbms9PSJzcGVjaWVzIixdLCAKICAgICAgIGFlcyh4PWFjY2VwdGVkX25hbWVfY291bnQsIAogICAgICAgICAgIHk9YWNjZXB0ZWRfbmFtZV9jb3VudF9jYXRlZ29yaWVzW2FzLmZhY3RvcihhY2NlcHRlZF9uYW1lX2NvdW50KV0sIAogICAgICAgICAgIGZpbGw9YWNjZXB0ZWRfcmFuaykpICsKICBnZW9tX3BvaW50KCkgKwogIAogIGFubm90YXRlKCJsaW5lIiwgeCA9IDE6bWF4KGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llcyksIHk9IGRlbnMKICAgICptYXgoKHRhYmxlKGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llcykvYXMubnVtZXJpYyhuYW1lcyh0YWJsZShhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXMpKSkpW2FzLmZhY3RvcihhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXMpXSkgL21heChkZW5zKSkrCiAgCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiTnVtYmVyIG9mIG9jY3VycmVuY2VzIGJ5IGFjY2VwdGVkIG5hbWUiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZzEwIiwgbmFtZSA9ICJOdW1iZXIgb2YgY29ycmVzcG9uZGluZyBhY2NlcHRlZCBuYW1lcyAobG9nLXNjYWxlKSIpICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWU9Ik9ic2VydmVkIGRpc3RyaWJ1dGlvbiIpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksIAogICAgICAgIHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIGdndGl0bGUoIkNvbXBhcmlzb24gYmV0d2VlbiBleHBlY3RlZCBhbmQgb2JzZXJ2ZWQgZGlzdHJpYnV0aW9ucyBvZiBudW1iZXIgb2Ygb2NjdXJyZW5jZXMiKSArCiAgZmFjZXRfZ3JpZChhY2NlcHRlZF9yYW5rIH4gLiwgc2NhbGVzID0gImZyZWUiKQoKYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzX2FnZ3JlZyA8LSBDZXRhY2VhX29jY19hZ2dyZWdbQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX3Jhbms9PSJzcGVjaWVzIixdJGFjY2VwdGVkX25hbWVfY291bnQKZGVuc19hZ2dyZWcgPC0gc2FwcGx5KDE6bWF4KGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19hZ2dyZWcpLCBmdW5jdGlvbihuKXsKICAgICBleHBlY3RlZF9kaXN0cmlidXRpb24obiwgb21lZ2EsIENldGFjZWFfb2NjX2FnZ3JlZ1tDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF0kYWdlX2NvbWJpbmVkX3JhbmdlKSR2YWx1ZQogICAgfSkKYWNjZXB0ZWRfbmFtZV9jb3VudF9jYXRlZ29yaWVzX2FnZ3JlZyA8LSB0YWJsZShhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXNfYWdncmVnKS9hcy5udW1lcmljKG5hbWVzKHRhYmxlKGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19hZ2dyZWcpKSkgICMgTnVtYmVyIG9mIGNhdGVnb3JpZXMgd2l0aCAxLCAyLCAzLCAuLi4gb2NjdXJyZW5jZXMgb2YgdGhlIHNhbWUgc3BlY2llcwoKIyBDb21wYXJlIHRoZSBjb3JyZWN0ZWQgb2JzZXJ2ZWQgZGlzdHJpYnV0aW9uIHdpdGggdGhlIHRoZW9yZXRpY2FsIGN1cnZlCmdncGxvdChDZXRhY2VhX29jY19hZ2dyZWdbQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX3Jhbms9PSJzcGVjaWVzIixdLCAKICAgICAgIGFlcyh4PWFjY2VwdGVkX25hbWVfY291bnQsCiAgICAgICAgICAgeT1hY2NlcHRlZF9uYW1lX2NvdW50X2NhdGVnb3JpZXNfYWdncmVnW2FzLmZhY3RvcihhY2NlcHRlZF9uYW1lX2NvdW50KV0sIAogICAgICAgICAgIGZpbGw9YWNjZXB0ZWRfcmFuaykpICsKICBnZW9tX3BvaW50KCkgKwogIAogIGFubm90YXRlKCJsaW5lIiwgeCA9IDE6bWF4KGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19hZ2dyZWcpLCB5PSBkZW5zX2FnZ3JlZwogICAgKm1heCgodGFibGUoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzX2FnZ3JlZykvYXMubnVtZXJpYyhuYW1lcyh0YWJsZShhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXNfYWdncmVnKSkpKVthcy5mYWN0b3IoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzX2FnZ3JlZyldKSAvbWF4KGRlbnNfYWdncmVnKSkgKwogIAogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIk51bWJlciBvZiBvY2N1cnJlbmNlcyBieSBhY2NlcHRlZCBuYW1lIikgKwogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIsIG5hbWUgPSAiTnVtYmVyIG9mIGNvcnJlc3BvbmRpbmcgYWNjZXB0ZWQgbmFtZXMgKGxvZy1zY2FsZSkiKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSJPYnNlcnZlZCBkaXN0cmlidXRpb24iKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCkpICsKICBnZ3RpdGxlKCJDb21wYXJpc29uIGJldHdlZW4gZXhwZWN0ZWQgYW5kIG9ic2VydmVkIGRpc3RyaWJ1dGlvbnMgb2YgbnVtYmVyIG9mIG9jY3VycmVuY2VzLCBhZnRlciBhZ2dyZWdhdGluZyBpbiBmb3JtYXRpb25zIikgKwogIGZhY2V0X2dyaWQoYWNjZXB0ZWRfcmFuayB+IC4sIHNjYWxlcyA9ICJmcmVlIikKCmFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19hZ2dyZWcgPC0gQ2V0YWNlYV9vY2NfYWdncmVnW0NldGFjZWFfb2NjX2FnZ3JlZyRhY2NlcHRlZF9yYW5rPT0ic3BlY2llcyIsXSRhY2NlcHRlZF9uYW1lX2NvdW50CmRlbnNfYWdncmVnIDwtIHNhcHBseSgxOm1heChhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXNfYWdncmVnKSwgZnVuY3Rpb24obil7CiAgICAgZXhwZWN0ZWRfZGlzdHJpYnV0aW9uKG4sIG9tZWdhLCBDZXRhY2VhX29jY19hZ2dyZWdbQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX3Jhbms9PSJzcGVjaWVzIixdJGFnZV9jb21iaW5lZF9yYW5nZSkkdmFsdWUKICAgIH0pCmFjY2VwdGVkX25hbWVfY291bnRfY2F0ZWdvcmllc19hZ2dyZWcgPC0gdGFibGUoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzX2FnZ3JlZykvYXMubnVtZXJpYyhuYW1lcyh0YWJsZShhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXNfYWdncmVnKSkpICAjIE51bWJlciBvZiBjYXRlZ29yaWVzIHdpdGggMSwgMiwgMywgLi4uIG9jY3VycmVuY2VzIG9mIHRoZSBzYW1lIHNwZWNpZXMKYGBgCgokXHRvJCBUaGUgY29ycmVzcG9uZGFuY2UgaXMgc3RpbGwgZ29vZCwgZXhjZXB0IGZvciB0d28gdGF4YSA6CgpgYGB7cn0KdGFibGUoZHJvcGxldmVscyhDZXRhY2VhX29jY19hZ2dyZWdbQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX3Jhbms9PSJzcGVjaWVzIixdW2FjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19hZ2dyZWc+MTAsXSRhY2NlcHRlZF9uYW1lKSkKYGBgCgpgYGB7ciwgd2FybmluZz1GQUxTRX0KQ2V0YWNlYV9vY2NfYWdncmVnJGFnZV9yYW5nZSA8LSBDZXRhY2VhX29jY19hZ2dyZWckbWF4X21hLUNldGFjZWFfb2NjX2FnZ3JlZyRtaW5fbWEKQ2V0YWNlYV9vY2NfYWdncmVnJG1pbl9taW5fbWEgPC0gYXBwbHkoQ2V0YWNlYV9vY2NfYWdncmVnLCAxLCBmdW5jdGlvbihYKXttaW4oQ2V0YWNlYV9vY2NfYWdncmVnW0NldGFjZWFfb2NjX2FnZ3JlZyRhZ2VfcmFuZ2U8MTAgJiBDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfbmFtZT09WFsiYWNjZXB0ZWRfbmFtZSJdLF0kbWluX21hKX0pCkNldGFjZWFfb2NjX2FnZ3JlZyRtYXhfbWF4X21hIDwtIGFwcGx5KENldGFjZWFfb2NjX2FnZ3JlZywgMSwgZnVuY3Rpb24oWCl7bWF4KENldGFjZWFfb2NjX2FnZ3JlZ1tDZXRhY2VhX29jY19hZ2dyZWckYWdlX3JhbmdlPDEwICYgQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX25hbWU9PVhbImFjY2VwdGVkX25hbWUiXSxdJG1heF9tYSl9KQpDZXRhY2VhX29jY19hZ2dyZWckYWdlX2NvbWJpbmVkX21lYW4gPC0gKENldGFjZWFfb2NjX2FnZ3JlZyRtaW5fbWluX21hICsgQ2V0YWNlYV9vY2NfYWdncmVnJG1heF9tYXhfbWEpLzIKQ2V0YWNlYV9vY2NfYWdncmVnJGFnZV9jb21iaW5lZF9yYW5nZSA8LSBDZXRhY2VhX29jY19hZ2dyZWckbWF4X21heF9tYS1DZXRhY2VhX29jY19hZ2dyZWckbWluX21pbl9tYQpDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfbmFtZV9jb3VudCA8LSBzYXBwbHkoQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX25hbWUsIGZ1bmN0aW9uKHgpe3RhYmxlKENldGFjZWFfb2NjX2FnZ3JlZyRhY2NlcHRlZF9uYW1lKVt4XX0pCkNldGFjZWFfb2NjX2FnZ3JlZyRvY2N1cnJlbmNlX2NvbWJpbmVkX2RlbnNpdHkgPC0gQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX25hbWVfY291bnQvQ2V0YWNlYV9vY2NfYWdncmVnJGFnZV9jb21iaW5lZF9yYW5nZQpgYGAKCmBgYHtyIGZpZy5oZWlnaHQ9NSwgbWVzc2FnZT1GQUxTRX0KYnJlYWtzIDwtIGMoMC4xMjUsMC4yNSwwLjUsMSwyLDQsOCwxNikKCnBfYmVmb3JlIDwtIGdncGxvdChDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rID09InNwZWNpZXMiICYgQ2V0YWNlYV9vY2MkYWdlX3JhbmdlPDEwLF0sIGFlcyh4PS1tYXhfbWEsIHk9YWNjZXB0ZWRfbmFtZSkpICsKICBnZW9tX3NlZ21lbnQoYWVzKHggPSAtbWF4X21heF9tYSwgeSA9IHJlb3JkZXIoYWNjZXB0ZWRfbmFtZSwgLWFnZV9jb21iaW5lZF9tZWFuKSwgeGVuZCA9IC1taW5fbWluX21hLCB5ZW5kPXJlb3JkZXIoYWNjZXB0ZWRfbmFtZSwgLWFnZV9jb21iaW5lZF9tZWFuKSwgY29sb3I9b2NjdXJyZW5jZV9jb21iaW5lZF9kZW5zaXR5KSwgYXJyb3c9YXJyb3coZW5kcyA9ICJib3RoIiwgYW5nbGU9OTAsIGxlbmd0aCA9IHVuaXQoMSwgIm1tIikpLCBhbHBoYT0wLjUpICsKICBnZW9tX3BvaW50KGFlcyh4PS1hZ2VfcnVuaWYpLCBjb2w9InJlZCIsIGNleD0wLjUsIGFscGhhPTAuNSkgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIlRpbWUgKE15KSIpICsKICBzY2FsZV95X2Rpc2NyZXRlKG5hbWUgPSAiU3BlY2llcyIpICsKICBsYWJzKGNvbG91cj0iT2NjdXJyZW5jZVxuZGVuc2l0eSIpICsKICB0aGVtZShheGlzLnRleHQueT1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcy55PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAidHJhbnNwYXJlbnQiLCBjb2xvciA9IE5BKSwKICAgICAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gInRyYW5zcGFyZW50IiwgY29sb3IgPSBOQSksCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAidHJhbnNwYXJlbnQiLCBjb2xvciA9IE5BKSkgKwogIHNjYWxlX2NvbG9yX2dyYWRpZW50bihjb2xvdXJzID0gYygiZGFya2JsdWUiLCAiZm9yZXN0Z3JlZW4iLCAiYmxhY2siKSwgdHJhbnM9ImxvZyIsIGJyZWFrcz1icmVha3MsIGxhYmVscz1icmVha3MpICsgCiAgZ2d0aXRsZShwYXN0ZSgiRGlzdHJpYnV0aW9ucyBvZiBzcGVjaWVzIGZvc3NpbCBhZ2UgcmFuZ2VzLCBiZWZvcmUgY29ycmVjdGluZyBzYW1wbGluZyAobiA9ICIsIGRpbShDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rID09InNwZWNpZXMiICYgQ2V0YWNlYV9vY2MkYWdlX3JhbmdlPDEwLF0pWzFdLCAiKSIsIHNlcD0iIikpCnBfYmVmb3JlCgpnZ3NhdmUoIkltYWdlcy9SYW5nZV9kaXN0cmlidXRpb25zX2JlZm9yZV9hZ2dyZWdhdGluZy5zdmciLCBwbG90ID0gcF9iZWZvcmUsIGRldmljZSA9ICJzdmciLCBiZyA9ICJ0cmFuc3BhcmVudCIpCgpwX2FmdGVyIDwtIGdncGxvdChDZXRhY2VhX29jY19hZ2dyZWdbQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX3JhbmsgPT0ic3BlY2llcyIgJiBDZXRhY2VhX29jY19hZ2dyZWckYWdlX3JhbmdlPDEwLF0sIGFlcyh4PS1tYXhfbWEsIHk9YWNjZXB0ZWRfbmFtZSkpICsKICBnZW9tX3NlZ21lbnQoYWVzKHggPSAtbWF4X21heF9tYSwgeSA9IHJlb3JkZXIoYWNjZXB0ZWRfbmFtZSwgLWFnZV9jb21iaW5lZF9tZWFuKSwgeGVuZCA9IC1taW5fbWluX21hLCB5ZW5kPXJlb3JkZXIoYWNjZXB0ZWRfbmFtZSwgLWFnZV9jb21iaW5lZF9tZWFuKSwgY29sb3I9b2NjdXJyZW5jZV9jb21iaW5lZF9kZW5zaXR5KSwgYXJyb3c9YXJyb3coZW5kcyA9ICJib3RoIiwgYW5nbGU9OTAsIGxlbmd0aCA9IHVuaXQoMSwgIm1tIikpLCBhbHBoYT0wLjUpICsKICBnZW9tX3BvaW50KGFlcyh4PS1hZ2VfcnVuaWYpLCBjb2w9InJlZCIsIGNleD0wLjUsIGFscGhhPTAuNSkgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIlRpbWUgKE15KSIpICsKICBzY2FsZV95X2Rpc2NyZXRlKG5hbWUgPSAiU3BlY2llcyIpICsKICBsYWJzKGNvbG91cj0iT2NjdXJyZW5jZVxuZGVuc2l0eSIpICsKICB0aGVtZShheGlzLnRleHQueT1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcy55PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAidHJhbnNwYXJlbnQiLCBjb2xvciA9IE5BKSwKICAgICAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gInRyYW5zcGFyZW50IiwgY29sb3IgPSBOQSksCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAidHJhbnNwYXJlbnQiLCBjb2xvciA9IE5BKSkgKwogIHNjYWxlX2NvbG9yX2dyYWRpZW50bihjb2xvdXJzID0gYygiZGFya2JsdWUiLCAiZm9yZXN0Z3JlZW4iLCAiYmxhY2siKSwgdHJhbnM9ImxvZyIsIGJyZWFrcz1icmVha3MsIGxhYmVscz1icmVha3MpICsgCiAgZ2d0aXRsZShwYXN0ZSgiRGlzdHJpYnV0aW9ucyBvZiBzcGVjaWVzIGZvc3NpbCBhZ2UgcmFuZ2VzLCBhZnRlciBjb3JyZWN0aW5nIHNhbXBsaW5nIChuID0gIiwgZGltKENldGFjZWFfb2NjX3NhbXBsZWQpWzFdLCAiKSIsIHNlcD0iIikpCnBfYWZ0ZXIKCmdnc2F2ZSgiSW1hZ2VzL1JhbmdlX2Rpc3RyaWJ1dGlvbnNfYWZ0ZXJfYWdncmVnYXRpbmcuc3ZnIiwgcGxvdCA9IHBfYWZ0ZXIsIGRldmljZSA9ICJzdmciLCBiZyA9ICJ0cmFuc3BhcmVudCIpCmBgYAoKYGBge3IgZmlnLmhlaWdodD02LCBtZXNzYWdlPUZBTFNFfQpjb25kaXRpb25zIDwtIENldGFjZWFfb2NjJGFjY2VwdGVkX3JhbmsgPT0ic3BlY2llcyIKCnAxIDwtIGdncGxvdChDZXRhY2VhX29jY1tjb25kaXRpb25zLF0sIGFlcyh4PS1hZ2VfcnVuaWYpKSArCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjUsIGFscGhhPTAuNSwgZmlsbD1OQSwgY29sPSJyZWQiKSArCiAgeGxpbSgtbWF4KENldGFjZWFfb2NjW2NvbmRpdGlvbnMsXSRhZ2VfcnVuaWYpLTEsIDEpICsKICB5bGltKDAsIDcwKSArCiAgdGhlbWVfdm9pZCgpCgpwMiA8LSBnZ3Bsb3QoQ2V0YWNlYV9vY2Nfc2FtcGxlZCwgYWVzKHg9LWFnZV9ydW5pZikpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuNSwgYWxwaGE9MC41LCBmaWxsPSJibHVlIikgKwogIHhsaW0oLW1heChDZXRhY2VhX29jY1tjb25kaXRpb25zLF0kYWdlX3J1bmlmKS0xLCAxKSArCiAgeWxpbSgwLCA3MCkgKwogIHRoZW1lX3ZvaWQoKQoKcDMgPC0gZ2dwbG90KENldGFjZWFfb2NjX2FnZ3JlZ1tDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfcmFuayA9PSJzcGVjaWVzIixdLCBhZXMoeD0tYWdlX3J1bmlmKSkgKwogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMC41LCBhbHBoYT0wLjUsIGZpbGw9ImdyZWVuIikgKwogIHhsaW0oLW1heChDZXRhY2VhX29jY1tjb25kaXRpb25zLF0kYWdlX3J1bmlmKS0xLCAxKSArCiAgeWxpbSgwLCA3MCkgKwogIHRoZW1lX3ZvaWQoKQoKcDEgKyBhbm5vdGF0aW9uX2N1c3RvbShnZ3Bsb3RHcm9iKHAyKSkgKyBnZ3RpdGxlKCJJbml0aWFsIG9jY3VycmVuY2VzIGRpc3RyaWJ1dGlvbiAocmVkKSBhbmQgY29tcGFyaXNvbiBhZnRlciBzdWItc2FtcGxpbmcgKGJsdWUpIikKCnAxICsgYW5ub3RhdGlvbl9jdXN0b20oZ2dwbG90R3JvYihwMykpICsgZ2d0aXRsZSgiSW5pdGlhbCBvY2N1cnJlbmNlcyBkaXN0cmlidXRpb24gKHJlZCkgYW5kIGNvbXBhcmlzb24gYWZ0ZXIgYWdncmVnYXRpbmcgaW4gZm9ybWF0aW9ucyAoZ3JlZW4pIikKCnBfYWxsIDwtIHAxICsgYW5ub3RhdGlvbl9jdXN0b20oZ2dwbG90R3JvYihwMikpICsgYW5ub3RhdGlvbl9jdXN0b20oZ2dwbG90R3JvYihwMykpICsgZ2d0aXRsZSgiSW5pdGlhbCBvY2N1cnJlbmNlcyBkaXN0cmlidXRpb24gKHJlZCkgYW5kIGNvbXBhcmlzb24gYWZ0ZXIgc3ViLXNhbXBsaW5nIChibHVlKSBvciBhZ2dyZWdhdGluZyBpbiBmb3JtYXRpb25zIChncmVlbikiKSArIHRoZW1lKHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gInRyYW5zcGFyZW50IiwgY29sb3IgPSBOQSkpCnBfYWxsCgpnZ3NhdmUoIkltYWdlcy9PY2N1cnJlbmNlX2Rpc3RyaWJ1dGlvbnNfY29tcGFyaXNvbi5zdmciLCBwbG90ID0gcF9hbGwsIGRldmljZSA9ICJzdmciLCBiZyA9ICJ0cmFuc3BhcmVudCIpCmBgYAoKJFx0byQgQ29tcGFyaW5nIHdpdGggdGhlIGluaXRpYWwgb2NjdXJyZW5jZXMgZGlzdHJpYnV0aW9uIGFuZCB3aXRoIHRoZSBkaXN0cmlidXRpb24gYWZ0ZXIgb3VyIGZpcnN0IHN1Yi1zYW1wbGluZyBpdCBhcHBlYXJzIHRoYXQgYm90aCBtZXRob2RzIGxlYWQgdG8gdmVyeSBzaW1pbGFyIGRpc3RyaWJ1dGlvbnMuIFRoaXMgY29uZm9ydHMgdXMgYWJvdXQgdGhlIHJvYnVzdG5lc3Mgb2YgdGhvc2UgYXBwcm9hY2hlcy4KClJlcGxhY2luZyBjb3V0cmllcyBieSBnZWxvZ2ljYWwgcGxhdGVzIHNlZW1zIHRvIG1ha2UgbW9yZSBzZW5zIGZyb20gYSBwYWxhZW9udG9sb2dpY2FsIHBlcnNwZWN0aXZlLCBzbyBsZXQncyB0cnkgaXQuCgojIyBBZ2dyZWdhdGUgb2NjdXJyZW5jZXMgd2l0aG91dCBmb3JtYXRpb24gYnkgZ2VvcGxhdGUgKyBlYXJseSBpbnRlcnZhbAoKYGBge3J9CkNldGFjZWFfb2NjX2FnZ3JlZyA8LSBjKCkKCiMgQnJvd3NlIGFsbCBnZW9wbGF0ZXMKZ2VvcGxhdGVzIDwtIGxldmVscyhkcm9wbGV2ZWxzKENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGZvcm1hdGlvbj09IiIsXSRnZW9wbGF0ZSkpCmZvciAoZ3AgaW4gZ2VvcGxhdGVzKXsKICBDZXRhY2VhX29jY19ncCA8LSBDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRmb3JtYXRpb249PSIiICYgQ2V0YWNlYV9vY2MkZ2VvcGxhdGU9PWdwLF0KICAKICAjIEJyb3dzZSBhbGwgZWFybHkgc3RyYXRpZ3JhcGhpYyBpbnRlcnZhbHMKICBlYXJseV9pbnRlcnZhbHMgPC0gbGV2ZWxzKGRyb3BsZXZlbHMoQ2V0YWNlYV9vY2NfZ3AkZWFybHlfaW50ZXJ2YWwpKQogIGZvciAoZWkgaW4gZWFybHlfaW50ZXJ2YWxzKXsKICAgIENldGFjZWFfb2NjX2dwX2VpIDwtIENldGFjZWFfb2NjX2dwW0NldGFjZWFfb2NjX2dwJGVhcmx5X2ludGVydmFsPT1laSxdCiAgICAKICAgICMgQnJvd3NlIGFsbCBhY2NlcHRlZCBuYW1lcyAmIHNhbXBsZSBvbmx5IDEgb2NjdXJyZW5jZQogICAgdGF4YSA8LSBsZXZlbHMoZHJvcGxldmVscyhDZXRhY2VhX29jY19ncF9laSRhY2NlcHRlZF9uYW1lKSkKICAgIGZvciAobmFtZSBpbiB0YXhhKXsKICAgICAgQ2V0YWNlYV9vY2NfYWdncmVnIDwtIHJiaW5kKENldGFjZWFfb2NjX2FnZ3JlZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNhbXBsZV9uKENldGFjZWFfb2NjX2dwX2VpW0NldGFjZWFfb2NjX2dwX2VpJGFjY2VwdGVkX25hbWU9PW5hbWUsXSwgc2l6ZSA9IDEpKQogICAgfQogIH0KfQoKIyBCcm93c2UgYWxsIGZvcm1hdGlvbnMKZm9ybWF0aW9ucyA8LSBsZXZlbHMoZHJvcGxldmVscyhDZXRhY2VhX29jYyRmb3JtYXRpb24pKQpmb3IgKGZvcm0gaW4gZm9ybWF0aW9uc1std2hpY2goZm9ybWF0aW9ucz09IiIpXSl7CiAgQ2V0YWNlYV9vY2NfZm9ybSA8LSBDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRmb3JtYXRpb249PWZvcm0sXQogIAogICMgQnJvd3NlIGFsbCBhY2NlcHRlZCBuYW1lcyBpbiBlYWNoIGZvcm1hdGlvbiAmIHNhbXBsZSBvbmx5IDEgb2NjdXJyZW5jZQogIHRheGEgPC0gbGV2ZWxzKGRyb3BsZXZlbHMoQ2V0YWNlYV9vY2NfZm9ybSRhY2NlcHRlZF9uYW1lKSkKICBmb3IgKG5hbWUgaW4gdGF4YSl7CiAgICBDZXRhY2VhX29jY19hZ2dyZWcgPC0gcmJpbmQoQ2V0YWNlYV9vY2NfYWdncmVnLCBzYW1wbGVfbihDZXRhY2VhX29jY19mb3JtW0NldGFjZWFfb2NjX2Zvcm0kYWNjZXB0ZWRfbmFtZT09bmFtZSxdLCBzaXplID0gMSkpCiAgfQp9CgpkYXRhLmZyYW1lKENldGFjZWFfb2NjID0gYyhkaW0oQ2V0YWNlYV9vY2MpWzFdLAogICAgICAgICAgICAgICAgICAgICAgICAgICBkaW0oQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayA9PSJzcGVjaWVzIixdKVsxXSksCiAgICAgICAgICAgQ2V0YWNlYV9vY2NfYWdncmVnID0gYyhkaW0oQ2V0YWNlYV9vY2NfYWdncmVnKVsxXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpbShDZXRhY2VhX29jY19hZ2dyZWdbQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX3JhbmsgPT0ic3BlY2llcyIsXSlbMV0pLAogICAgICAgICAgIHJlbW92ZWQgPSBjKGRpbShDZXRhY2VhX29jYylbMV0tZGltKENldGFjZWFfb2NjX2FnZ3JlZylbMV0sCiAgICAgICAgICAgICAgICAgICAgICAgZGltKENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGFjY2VwdGVkX3JhbmsgPT0ic3BlY2llcyIsXSlbMV0tZGltKENldGFjZWFfb2NjX2FnZ3JlZ1tDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfcmFuayA9PSJzcGVjaWVzIixdKVsxXSksCiAgICAgICAgICAgcm93Lm5hbWVzID0gYygiTnVtYmVyIG9mIG9jY3VycmVuY2VzIiwgIk51bWJlciBvZiBvY2N1cnJlbmNlcyAoc3BlY2llcyBvbmx5KSIpKQpgYGAKCk1vcmUgb2NjdXJyZW5jZXMgcmVtYWluIGFmdGVyIGFnZ3JlZ2F0aW5nIHdpdGggdGhpcyBuZXcgbWV0aG9kLiBMZXQncyBjb21wYXJlIGFnYWluIHdpdGggdGhlIHRoZW9yZXRpY2FsIGRpc3RyaWJ1dGlvbiA6CgpgYGB7ciBmaWcuaGVpZ2h0PTd9CiMgUmVjb3VudCB0aGUgbnVtYmVyIG9mIG9jY3VycmVuY2VzIHdpdGggdGhlIHNhbWUgYWNjZXB0ZWQgbmFtZSBhZnRlciB0aGUgYWdncmVnYXRpb24KQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX25hbWVfY291bnQgPC0gc2FwcGx5KENldGFjZWFfb2NjX2FnZ3JlZyRhY2NlcHRlZF9uYW1lLCBmdW5jdGlvbih4KXt0YWJsZShDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfbmFtZSlbeF19KQoKb21lZ2EgPC0gMC4xNQphY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXMgPC0gQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF0kYWNjZXB0ZWRfbmFtZV9jb3VudApkZW5zIDwtIHNhcHBseSgxOm1heChhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXMpLCBmdW5jdGlvbihuKXsgZXhwZWN0ZWRfZGlzdHJpYnV0aW9uKG4sIG9tZWdhLCBDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rPT0ic3BlY2llcyIsXSRhZ2VfY29tYmluZWRfcmFuZ2UpJHZhbHVlIH0pCmFjY2VwdGVkX25hbWVfY291bnRfY2F0ZWdvcmllcyA8LSB0YWJsZShhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXMpL2FzLm51bWVyaWMobmFtZXModGFibGUoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzKSkpICAjIE51bWJlciBvZiBjYXRlZ29yaWVzIHdpdGggMSwgMiwgMywgLi4uIG9jY3VycmVuY2VzIG9mIHRoZSBzYW1lIHNwZWNpZXMKCiMgQ29tcGFyZSB0aGUgaW5pdGlhbCBvYnNlcnZlZCBkaXN0cmlidXRpb24gd2l0aCB0aGUgdGhlb3JldGljYWwgY3VydmUKZ2dwbG90KENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGFjY2VwdGVkX3Jhbms9PSJzcGVjaWVzIixdLCAKICAgICAgIGFlcyh4PWFjY2VwdGVkX25hbWVfY291bnQsIAogICAgICAgICAgIHk9YWNjZXB0ZWRfbmFtZV9jb3VudF9jYXRlZ29yaWVzW2FzLmZhY3RvcihhY2NlcHRlZF9uYW1lX2NvdW50KV0sIAogICAgICAgICAgIGZpbGw9YWNjZXB0ZWRfcmFuaykpICsKICBnZW9tX3BvaW50KCkgKwogIAogIGFubm90YXRlKCJsaW5lIiwgeCA9IDE6bWF4KGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llcyksIHk9IGRlbnMKICAgICptYXgoKHRhYmxlKGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llcykvYXMubnVtZXJpYyhuYW1lcyh0YWJsZShhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXMpKSkpW2FzLmZhY3RvcihhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXMpXSkgL21heChkZW5zKSkrCiAgCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiTnVtYmVyIG9mIG9jY3VycmVuY2VzIGJ5IGFjY2VwdGVkIG5hbWUiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZzEwIiwgbmFtZSA9ICJOdW1iZXIgb2YgY29ycmVzcG9uZGluZyBhY2NlcHRlZCBuYW1lcyAobG9nLXNjYWxlKSIpICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWU9Ik9ic2VydmVkIGRpc3RyaWJ1dGlvbiIpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksIAogICAgICAgIHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIGdndGl0bGUoIkNvbXBhcmlzb24gYmV0d2VlbiBleHBlY3RlZCBhbmQgb2JzZXJ2ZWQgZGlzdHJpYnV0aW9ucyBvZiBudW1iZXIgb2Ygb2NjdXJyZW5jZXMiKSArCiAgZmFjZXRfZ3JpZChhY2NlcHRlZF9yYW5rIH4gLiwgc2NhbGVzID0gImZyZWUiKQoKYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzX2FnZ3JlZyA8LSBDZXRhY2VhX29jY19hZ2dyZWdbQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX3Jhbms9PSJzcGVjaWVzIixdJGFjY2VwdGVkX25hbWVfY291bnQKZGVuc19hZ2dyZWcgPC0gc2FwcGx5KDE6bWF4KGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19hZ2dyZWcpLCBmdW5jdGlvbihuKXsKICAgICBleHBlY3RlZF9kaXN0cmlidXRpb24obiwgb21lZ2EsIENldGFjZWFfb2NjX2FnZ3JlZ1tDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF0kYWdlX2NvbWJpbmVkX3JhbmdlKSR2YWx1ZQogICAgfSkKYWNjZXB0ZWRfbmFtZV9jb3VudF9jYXRlZ29yaWVzX2FnZ3JlZyA8LSB0YWJsZShhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXNfYWdncmVnKS9hcy5udW1lcmljKG5hbWVzKHRhYmxlKGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19hZ2dyZWcpKSkgICMgTnVtYmVyIG9mIGNhdGVnb3JpZXMgd2l0aCAxLCAyLCAzLCAuLi4gb2NjdXJyZW5jZXMgb2YgdGhlIHNhbWUgc3BlY2llcwoKIyBDb21wYXJlIHRoZSBjb3JyZWN0ZWQgb2JzZXJ2ZWQgZGlzdHJpYnV0aW9uIHdpdGggdGhlIHRoZW9yZXRpY2FsIGN1cnZlCmdncGxvdChDZXRhY2VhX29jY19hZ2dyZWdbQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX3Jhbms9PSJzcGVjaWVzIixdLCAKICAgICAgIGFlcyh4PWFjY2VwdGVkX25hbWVfY291bnQsCiAgICAgICAgICAgeT1hY2NlcHRlZF9uYW1lX2NvdW50X2NhdGVnb3JpZXNfYWdncmVnW2FzLmZhY3RvcihhY2NlcHRlZF9uYW1lX2NvdW50KV0sIAogICAgICAgICAgIGZpbGw9YWNjZXB0ZWRfcmFuaykpICsKICBnZW9tX3BvaW50KCkgKwogIAogIGFubm90YXRlKCJsaW5lIiwgeCA9IDE6bWF4KGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19hZ2dyZWcpLCB5PSBkZW5zX2FnZ3JlZwogICAgKm1heCgodGFibGUoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzX2FnZ3JlZykvYXMubnVtZXJpYyhuYW1lcyh0YWJsZShhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXNfYWdncmVnKSkpKVthcy5mYWN0b3IoYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzX2FnZ3JlZyldKSAvbWF4KGRlbnNfYWdncmVnKSkgKwogIAogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIk51bWJlciBvZiBvY2N1cnJlbmNlcyBieSBhY2NlcHRlZCBuYW1lIikgKwogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9ICJsb2cxMCIsIG5hbWUgPSAiTnVtYmVyIG9mIGNvcnJlc3BvbmRpbmcgYWNjZXB0ZWQgbmFtZXMgKGxvZy1zY2FsZSkiKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSJPYnNlcnZlZCBkaXN0cmlidXRpb24iKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCkpICsKICBnZ3RpdGxlKCJDb21wYXJpc29uIGJldHdlZW4gZXhwZWN0ZWQgYW5kIG9ic2VydmVkIGRpc3RyaWJ1dGlvbnMgb2YgbnVtYmVyIG9mIG9jY3VycmVuY2VzLCBhZnRlciBhZ2dyZWdhdGluZyBpbiBnZW9wbGF0ZXMiKSArCiAgZmFjZXRfZ3JpZChhY2NlcHRlZF9yYW5rIH4gLiwgc2NhbGVzID0gImZyZWUiKQoKYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzX2FnZ3JlZyA8LSBDZXRhY2VhX29jY19hZ2dyZWdbQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX3Jhbms9PSJzcGVjaWVzIixdJGFjY2VwdGVkX25hbWVfY291bnQKZGVuc19hZ2dyZWcgPC0gc2FwcGx5KDE6bWF4KGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19hZ2dyZWcpLCBmdW5jdGlvbihuKXsKICAgICBleHBlY3RlZF9kaXN0cmlidXRpb24obiwgb21lZ2EsIENldGFjZWFfb2NjX2FnZ3JlZ1tDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF0kYWdlX2NvbWJpbmVkX3JhbmdlKSR2YWx1ZQogICAgfSkKYWNjZXB0ZWRfbmFtZV9jb3VudF9jYXRlZ29yaWVzX2FnZ3JlZyA8LSB0YWJsZShhY2NlcHRlZF9uYW1lX2NvdW50X3NwZWNpZXNfYWdncmVnKS9hcy5udW1lcmljKG5hbWVzKHRhYmxlKGFjY2VwdGVkX25hbWVfY291bnRfc3BlY2llc19hZ2dyZWcpKSkgICMgTnVtYmVyIG9mIGNhdGVnb3JpZXMgd2l0aCAxLCAyLCAzLCAuLi4gb2NjdXJyZW5jZXMgb2YgdGhlIHNhbWUgc3BlY2llcwpgYGAKCiRcdG8kIFRoZSBjb3JyZXNwb25kYW5jZSBpcyBzdGlsbCBnb29kLCBleGNlcHQgZm9yIHR3byB0YXhhIDoKCmBgYHtyfQp0YWJsZShkcm9wbGV2ZWxzKENldGFjZWFfb2NjX2FnZ3JlZ1tDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF1bYWNjZXB0ZWRfbmFtZV9jb3VudF9zcGVjaWVzX2FnZ3JlZz4xMCxdJGFjY2VwdGVkX25hbWUpKQpgYGAKCmBgYHtyIGZpZy5oZWlnaHQ9Nn0KY29uZGl0aW9ucyA8LSBDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rID09InNwZWNpZXMiCgpwMSA8LSBnZ3Bsb3QoQ2V0YWNlYV9vY2NbY29uZGl0aW9ucyxdLCBhZXMoeD0tYWdlX3J1bmlmKSkgKwogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMC41LCBhbHBoYT0wLjUsIGZpbGw9TkEsIGNvbD0icmVkIikgKwogIHhsaW0oLW1heChDZXRhY2VhX29jY1tjb25kaXRpb25zLF0kYWdlX3J1bmlmKS0xLCAxKSArCiAgeWxpbSgwLCA3MCkgKwogIHRoZW1lX3ZvaWQoKQoKcDIgPC0gZ2dwbG90KENldGFjZWFfb2NjX3NhbXBsZWQsIGFlcyh4PS1hZ2VfcnVuaWYpKSArCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjUsIGFscGhhPTAuNSwgZmlsbD0iYmx1ZSIpICsKICB4bGltKC1tYXgoQ2V0YWNlYV9vY2NbY29uZGl0aW9ucyxdJGFnZV9ydW5pZiktMSwgMSkgKwogIHlsaW0oMCwgNzApICsKICB0aGVtZV92b2lkKCkKCnAzIDwtIGdncGxvdChDZXRhY2VhX29jY19hZ2dyZWdbQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX3JhbmsgPT0ic3BlY2llcyIsXSwgYWVzKHg9LWFnZV9ydW5pZikpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuNSwgYWxwaGE9MC41LCBmaWxsPSJncmVlbiIpICsKICB4bGltKC1tYXgoQ2V0YWNlYV9vY2NbY29uZGl0aW9ucyxdJGFnZV9ydW5pZiktMSwgMSkgKwogIHlsaW0oMCwgNzApICsKICB0aGVtZV92b2lkKCkKCnAxICsgYW5ub3RhdGlvbl9jdXN0b20oZ2dwbG90R3JvYihwMikpICsgZ2d0aXRsZSgiSW5pdGlhbCBvY2N1cnJlbmNlcyBkaXN0cmlidXRpb24gKHJlZCkgYW5kIGNvbXBhcmlzb24gYWZ0ZXIgc3ViLXNhbXBsaW5nIChibHVlKSIpCgpwMSArIGFubm90YXRpb25fY3VzdG9tKGdncGxvdEdyb2IocDMpKSArIGdndGl0bGUoIkluaXRpYWwgb2NjdXJyZW5jZXMgZGlzdHJpYnV0aW9uIChyZWQpIGFuZCBjb21wYXJpc29uIGFmdGVyIGFnZ3JlZ2F0aW5nIGluIGdlb3BsYXRlcyAoZ3JlZW4pIikKCnAxICsgYW5ub3RhdGlvbl9jdXN0b20oZ2dwbG90R3JvYihwMikpICsgYW5ub3RhdGlvbl9jdXN0b20oZ2dwbG90R3JvYihwMykpICsgZ2d0aXRsZSgiSW5pdGlhbCBvY2N1cnJlbmNlcyBkaXN0cmlidXRpb24gKHJlZCkgYW5kIGNvbXBhcmlzb24gYWZ0ZXIgc3ViLXNhbXBsaW5nIChibHVlKSBvciBhZ2dyZWdhdGluZyBpbiBnZW9wbGF0ZXMgKGdyZWVuKSIpCmBgYAoKJFx0byQgRGVsaW1pdGluZyBieSBnZW9sb2dpY2FsIHBsYXRlcyAoKyBhZ2UpIGluc3RlYWQgb2YgY291bnRyaWVzICgrIGFnZSkgbGVhZHMgdG8gc2ltaWxhciBkaXN0cmlidXRpb25zLCBzbyB3ZSB3aWxsIGtlZXAgaXQuCgojIyBDaGVjayB0aGF0IHRoZSBzYW1wbGluZyBtZXRob2RzIGRvIG5vdCBpbnRyb2R1Y2UgYmlhc2VzIGluIHRoZSByZXBhcnRpdGlvbiBiZXR3ZWVuIE9kb250b2NldGkgYW5kIE15c3RpY2V0aQoKTXlzdGVjZXRlcyBhcmUgdXN1YWxseSBsYXJnZXIgdGhhbiBvZG9udG9jZXRlcywgYW5kIHNpemUgaXMgYXNzb2NpYXRlZCB3aXRoIGEgd2lkZXIgZ2VvZ3JhcGhpYyByYW5nZSBzbyBzaW5jZSB3ZSBhcmUgc3Vic2FtcGxpbmcgb2NjdXJyZW5jZXMgYWNjb3JkaW5nIHRvIGdlb2xvZ2ljYWwgZm9ybWF0aW9uIHdlIG1heSBiZSBiaWFzaW5nIG91ciBkYXRhIHRvd2FyZHMgbW9yZSB3aWRlc3ByZWFkIHNwZWNpZXMsIHRoZXJlZm9yZSB0b3dhcmRzIG15c3RlY2V0ZXMuCgpMb29rIGF0IHRoZSBmYW1pbGllcyBmaXJzdCA6CgpgYGB7ciBmaWcuaGVpZ2h0PTZ9CmZhbWlsaWVzIDwtIHJiaW5kKENldGFjZWFfb2NjID0gQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuaz09InNwZWNpZXMiLF0sCiAgICAgICAgICAgICAgICAgIENldGFjZWFfb2NjX3NhbXBsZWQgPSBDZXRhY2VhX29jY19zYW1wbGVkLAogICAgICAgICAgICAgICAgICBDZXRhY2VhX29jY19hZ2dyZWcgPSBDZXRhY2VhX29jY19hZ2dyZWdbQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX3Jhbms9PSJzcGVjaWVzIixdKSAlPiUKICAgICAgICAgICAgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4odmFyID0gIkRhdGFzZXQiKQoKZmFtaWxpZXMgPC0gZmFtaWxpZXNbLGMoIkRhdGFzZXQiLCAiZmFtaWx5IildCmZhbWlsaWVzJERhdGFzZXQgPC0gc2FwcGx5KGZhbWlsaWVzJERhdGFzZXQsIGdzdWIsIHBhdHRlcm49IlxcLi4qIiwgcmVwbGFjZW1lbnQ9IiIpCgpnZ3Bsb3QoZmFtaWxpZXNbZmFtaWxpZXMkZmFtaWx5ICE9ICJOT19GQU1JTFlfU1BFQ0lGSUVEIixdLCBhZXMoeCA9IERhdGFzZXQsIGZpbGwgPSBmYW1pbHkpKSArIAogICAgZ2VvbV9iYXIocG9zaXRpb249ImZpbGwiLCBjb2w9ImJsYWNrIikKYGBgCgokXHRvJCBUaGUgZmFtaWx5IHJlcGFydGl0aW9ucyB2YXJ5IGEgYml0IGFmdGVyIHN1YnNhbXBsaW5nLCBidXQgYmVjYXVzZSBvZiB0aGUgbGltaXRlZCBudW1iZXIgb2Ygc3BlY2llcyBieSBmYW1pbHkgdGhlIGZhY3QgdGhhdCB3ZSBjb3JyZWN0ZWQgdGhlIG92ZXJzYW1wbGluZyBvZiBzb21lIHNwZWNpZXMgY291bGQgaGF2ZSBhIGRpc3Byb3BvcnRpb25hdGUgZWZmZWN0LgoKTGV0J3MgbG9vayByYXRoZXIgYXQgYSBoaWdoZXIgdGF4b25vbWljIHJhbmssIGJ5IGltcG9ydGluZyB0aGUgdG9wb2xvZ3kgb2YgY2V0YWNlYW4gZmFtaWxpZXMgKGZyb20gTWFyeCBldCBhbC4gMjAxNikgOgoKYGBge3IgZmlnLndpZHRoPTEwfQpmYW1pbGllc190cmVlIDwtIGFwZTo6cmVhZC50cmVlKCJiam9lbGxlLXN0cmF0aWdyYXBoaWNfYWdlX3VuY2VydGFpbnR5X1NJLTliYmNlZjIvY2V0YWNlYW5zX2RhdGEvZm9zc2lscy9mYW1pbGllcy50cmUiKQpnZ3RyZWUoZmFtaWxpZXNfdHJlZSkgKwogIGdlb21fdGlwbGFiKCkgKwogIGdlb21fbm9kZWxhYigpICsgCiAgZ2d0aXRsZSgiVG9wb2xvZ3kgb2YgY2V0YWNlYW4gZmFtaWxpZXMiKSArCiAgeGxpbSgwLCA4KQoKZmFtaWxpZXNfdHJlZV9PZG9udG9jZXRpIDwtIGNhc3Rvcjo6Z2V0X3N1YnRyZWVfYXRfbm9kZShmYW1pbGllc190cmVlLCAiT2RvbnRvY2V0aSIpJHN1YnRyZWUKZ2d0cmVlKGZhbWlsaWVzX3RyZWVfT2RvbnRvY2V0aSkgKwogIGdlb21fdGlwbGFiKCkgKwogIGdlb21fbm9kZWxhYigpICsgCiAgZ2d0aXRsZSgiVG9wb2xvZ3kgb2Ygb2RvbnRvY2V0ZSBmYW1pbGllcyIpICsKICB4bGltKDAsIDUpCgpmYW1pbGllc190cmVlX015c3RpY2V0aSA8LSBjYXN0b3I6OmdldF9zdWJ0cmVlX2F0X25vZGUoZmFtaWxpZXNfdHJlZSwgIk15c3RpY2V0aSIpJHN1YnRyZWUKZ2d0cmVlKGZhbWlsaWVzX3RyZWVfTXlzdGljZXRpKSArCiAgZ2VvbV90aXBsYWIoKSArCiAgZ2VvbV9ub2RlbGFiKCkgKyAKICBnZ3RpdGxlKCJUb3BvbG9neSBvZiBteXN0aWNldGUgZmFtaWxpZXMiKSArCiAgeGxpbSgwLCA1KQoKZmFtaWxpZXNfdHJlZV9TdGVtIDwtIGNhc3Rvcjo6Z2V0X3N1YnRyZWVfd2l0aF90aXBzKGZhbWlsaWVzX3RyZWUsIG9taXRfdGlwcyA9IGMoZmFtaWxpZXNfdHJlZV9PZG9udG9jZXRpJHRpcC5sYWJlbCwgZmFtaWxpZXNfdHJlZV9NeXN0aWNldGkkdGlwLmxhYmVsKSkkc3VidHJlZQpnZ3RyZWUoZmFtaWxpZXNfdHJlZV9TdGVtKSArCiAgZ2VvbV90aXBsYWIoKSArCiAgZ2VvbV9ub2RlbGFiKCkgKyAKICBnZ3RpdGxlKCJUb3BvbG9neSBvZiBhcmNoZW9jZXRlIGZhbWlsaWVzIikgKwogIHhsaW0oMCwgMykKYGBgCgpgYGB7cn0KT2RvbnRvY2V0aV9mYW1pbGllcyA8LSBjKGZhbWlsaWVzX3RyZWVfT2RvbnRvY2V0aVtjKCJ0aXAubGFiZWwiLCAibm9kZS5sYWJlbCIpXSwgIktlbnRyaW9kb250aWRhZSIsICJTcXVhbG96aXBoaWlkYWUiKQpNeXN0aWNldGlfZmFtaWxpZXMgPC0gZmFtaWxpZXNfdHJlZV9NeXN0aWNldGlbYygidGlwLmxhYmVsIiwgIm5vZGUubGFiZWwiKV0KYXJjaGFlb2NldGVfZmFtaWxpZXMgPC0gZmFtaWxpZXNfdHJlZV9TdGVtW2MoInRpcC5sYWJlbCIsICJub2RlLmxhYmVsIildCgpmYW1pbHlfdG9fdGF4b25vbWljX2dyb3VwIDwtIGZ1bmN0aW9uKGZhbWlseSl7CiAgcmV0dXJuKGMoIk9kb250b2NldGkiLCAiTXlzdGljZXRpIiwgImFyY2hhZW9jZXRlcyIpWwogICAgZ3JlcChwYXR0ZXJuID0gZmFtaWx5LAogICAgICAgICB4ID0gbGlzdChPZG9udG9jZXRpX2ZhbWlsaWVzLCBNeXN0aWNldGlfZmFtaWxpZXMsIGFyY2hhZW9jZXRlX2ZhbWlsaWVzKSldKQogIH0KCmZhbWlsaWVzJFRheG9ub21pYy5ncm91cCA8LSBhcy5jaGFyYWN0ZXIoc2FwcGx5KGZhbWlsaWVzJGZhbWlseSwgZmFtaWx5X3RvX3RheG9ub21pY19ncm91cCkpCmdncGxvdChmYW1pbGllc1tmYW1pbGllcyRmYW1pbHkgIT0gIk5PX0ZBTUlMWV9TUEVDSUZJRUQiLF0sIGFlcyh4ID0gRGF0YXNldCwgZmlsbCA9IFRheG9ub21pYy5ncm91cCkpICsgCiAgICBnZW9tX2Jhcihwb3NpdGlvbj0iZmlsbCIsIGNvbD0iYmxhY2siKQoKZ2dwbG90KGZhbWlsaWVzW2ZhbWlsaWVzJGZhbWlseSAhPSAiTk9fRkFNSUxZX1NQRUNJRklFRCIgJiBmYW1pbGllcyRUYXhvbm9taWMuZ3JvdXAgIT0gImFyY2hhZW9jZXRlcyIsXSwgYWVzKHggPSBEYXRhc2V0LCBmaWxsID0gVGF4b25vbWljLmdyb3VwKSkgKwogIGdlb21fYmFyKHBvc2l0aW9uPSJmaWxsIiwgY29sPSJibGFjayIpCmBgYAoKJFx0byQgVGhlcmUgaXMgYSBzbWFsbGVyIHByb3BvcnRpb24gb2YgYXJjaGVvY2V0ZSBvY2N1cnJlbmNlcyBhZnRlciBlaXRoZXIgc2FtcGxpbmcsIGJlY2F1c2UgYSBodWdlIGNsdXN0ZXIgaXMgc3Vic2FtcGxlZCBhcm91bmQgMzUgTXkgYWdvLCBidXQgdGhpcyBlZmZlY3QgaXMgZXhwZWN0ZWQuIEhvd2V2ZXIsIGZvciB0aGUgTXlzdGljZXRpIHZzLiBPZG90b2NldGkgdGhlcmUgaXMgbm8gaHVnZSBhcHBhcmVudCBiaWFzLCBlc3BlY2lhbGx5IHdpdGggdGhlIGFnZ3JlZ2F0aW5nIG1ldGhvZC4KCmBgYHtyfQojIHdyaXRlKENldGFjZWFfb2NjX2FnZ3JlZ1tDZXRhY2VhX29jY19hZ2dyZWckYWNjZXB0ZWRfcmFuayA9PSJzcGVjaWVzIixdJGFnZV9ydW5pZiwgCiMgICAgICAgZmlsZSA9ICJkYXRhLWNldGFjZWFucy9DZXRhY2VhX2FnZV9ydW5pZl9hZ2Vfc3BlY2llc19jb3JyZWN0ZWQuY3N2IiwgCiMgICAgICAgc2VwID0gIjsgIiwgCiMgICAgICAgbmNvbHVtbnMgPSBkaW0oQ2V0YWNlYV9vY2NfYWdncmVnW0NldGFjZWFfb2NjX2FnZ3JlZyRhY2NlcHRlZF9yYW5rID09InNwZWNpZXMiLF0pWzFdKQp3cml0ZS50YWJsZShDZXRhY2VhX29jY19hZ2dyZWdbQ2V0YWNlYV9vY2NfYWdncmVnJGFjY2VwdGVkX3JhbmsgJWluJSBjKCJzcGVjaWVzIiwgImdlbnVzIiksIGMoIm1pbl9tYSIsICJtYXhfbWEiKV0sCiAgICAgICAgICAgIGZpbGU9ImRhdGEtY2V0YWNlYW5zL0NldGFjZWFfb2NjdXJyZW5jZXNfbWluX21heF9hZ2Vfc3BlY2llc19jb3JyZWN0ZWQuY3N2Iiwgc2VwPSIsIiwgcm93Lm5hbWVzPUZBTFNFLCBjb2wubmFtZXM9RkFMU0UpCmBgYAoKIyBGYXN0ZXIgZ2VudXMtbGV2ZWwgYW5hbHlzaXMKCmBgYHtyfQpDZXRhY2VhX29jY19hZ2dyZWdfZ2VuIDwtIGMoKQoKIyBCcm93c2UgYWxsIGZvcm1hdGlvbnMKZm9ybWF0aW9ucyA8LSBsZXZlbHMoZHJvcGxldmVscyhDZXRhY2VhX29jYyRmb3JtYXRpb24pKQpmb3IgKGZvcm0gaW4gZm9ybWF0aW9uc1std2hpY2goZm9ybWF0aW9ucz09IiIpXSl7CiAgQ2V0YWNlYV9vY2NfZm9ybSA8LSBDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRmb3JtYXRpb249PWZvcm0sXQogIAogICMgQnJvd3NlIGFsbCBnZW5lcmEgaW4gZWFjaCBmb3JtYXRpb24gJiBzYW1wbGUgb25seSAxIG9jY3VycmVuY2UKICBnZW5lcmEgPC0gbGV2ZWxzKGRyb3BsZXZlbHMoQ2V0YWNlYV9vY2NfZm9ybSRnZW51cykpCiAgZm9yIChnZW4gaW4gZ2VuZXJhKXsKICAgIENldGFjZWFfb2NjX2FnZ3JlZ19nZW4gPC0gcmJpbmQoQ2V0YWNlYV9vY2NfYWdncmVnX2dlbiwgc2FtcGxlX24oQ2V0YWNlYV9vY2NfZm9ybVtDZXRhY2VhX29jY19mb3JtJGdlbnVzPT1nZW4sXSwgc2l6ZSA9IDEpKQogIH0KfQoKIyBCcm93c2UgYWxsIGdlb3BsYXRlcwpnZW9wbGF0ZXMgPC0gbGV2ZWxzKGRyb3BsZXZlbHMoQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkZm9ybWF0aW9uPT0iIixdJGdlb3BsYXRlKSkKZm9yIChncCBpbiBnZW9wbGF0ZXMpewogIENldGFjZWFfb2NjX2dwIDwtIENldGFjZWFfb2NjW0NldGFjZWFfb2NjJGZvcm1hdGlvbj09IiIgJiBDZXRhY2VhX29jYyRnZW9wbGF0ZT09Z3AsXQogIAogICMgQnJvd3NlIGFsbCBlYXJseSBzdHJhdGlncmFwaGljIGludGVydmFscwogIGVhcmx5X2ludGVydmFscyA8LSBsZXZlbHMoZHJvcGxldmVscyhDZXRhY2VhX29jY19ncCRlYXJseV9pbnRlcnZhbCkpCiAgZm9yIChlaSBpbiBlYXJseV9pbnRlcnZhbHMpewogICAgQ2V0YWNlYV9vY2NfZ3BfZWkgPC0gQ2V0YWNlYV9vY2NfZ3BbQ2V0YWNlYV9vY2NfZ3AkZWFybHlfaW50ZXJ2YWw9PWVpLF0KICAgIAogICAgIyBCcm93c2UgYWxsIGdlbmVyYSAmIHNhbXBsZSBvbmx5IDEgb2NjdXJyZW5jZQogICAgZ2VuZXJhIDwtIGxldmVscyhkcm9wbGV2ZWxzKENldGFjZWFfb2NjX2dwX2VpJGdlbnVzKSkKICAgIGZvciAoZ2VuIGluIGdlbmVyYSl7CiAgICAgIENldGFjZWFfb2NjX2FnZ3JlZ19nZW4gPC0gcmJpbmQoQ2V0YWNlYV9vY2NfYWdncmVnX2dlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNhbXBsZV9uKENldGFjZWFfb2NjX2dwX2VpW0NldGFjZWFfb2NjX2dwX2VpJGdlbnVzPT1nZW4sXSwgc2l6ZSA9IDEpKQogICAgfQogIH0KfQoKZGF0YS5mcmFtZShDZXRhY2VhX29jYyA9IGMoZGltKENldGFjZWFfb2NjKVsxXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpbShDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rICVpbiUgYygic3BlY2llcyIsICJnZW51cyIpLF0pWzFdKSwKICAgICAgICAgICBDZXRhY2VhX29jY19hZ2dyZWdfZ2VuID0gYyhkaW0oQ2V0YWNlYV9vY2NfYWdncmVnX2dlbilbMV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaW0oQ2V0YWNlYV9vY2NfYWdncmVnX2dlbltDZXRhY2VhX29jY19hZ2dyZWdfZ2VuJGFjY2VwdGVkX3JhbmsgJWluJSBjKCJzcGVjaWVzIiwgImdlbnVzIiksXSlbMV0pLAogICAgICAgICAgIHJlbW92ZWQgPSBjKGRpbShDZXRhY2VhX29jYylbMV0tZGltKENldGFjZWFfb2NjX2FnZ3JlZ19nZW4pWzFdLAogICAgICAgICAgICAgICAgICAgICAgIGRpbShDZXRhY2VhX29jY1tDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rICVpbiUgYygic3BlY2llcyIsICJnZW51cyIpLF0pWzFdLWRpbShDZXRhY2VhX29jY19hZ2dyZWdfZ2VuW0NldGFjZWFfb2NjX2FnZ3JlZ19nZW4kYWNjZXB0ZWRfcmFuayAlaW4lIGMoInNwZWNpZXMiLCAiZ2VudXMiKSxdKVsxXSksCiAgICAgICAgICAgcm93Lm5hbWVzID0gYygiTnVtYmVyIG9mIG9jY3VycmVuY2VzIiwgIk51bWJlciBvZiBvY2N1cnJlbmNlcyAoc3BlY2llcyBhbmQgZ2VuZXJhIG9ubHkpIikpCmBgYAoKTW9yZSBvY2N1cnJlbmNlcyByZW1haW4gYWZ0ZXIgYWdncmVnYXRpbmcgd2l0aCB0aGlzIG5ldyBtZXRob2QuIExldCdzIGNvbXBhcmUgYWdhaW4gd2l0aCB0aGUgdGhlb3JldGljYWwgZGlzdHJpYnV0aW9uIDoKCmBgYHtyIGZpZy5oZWlnaHQ9N30KIyBSZWNvdW50IHRoZSBudW1iZXIgb2Ygb2NjdXJyZW5jZXMgd2l0aCB0aGUgc2FtZSBnZW51cyBhZnRlciB0aGUgYWdncmVnYXRpb24KQ2V0YWNlYV9vY2MkZ2VudXNfY291bnQgPC0gc2FwcGx5KENldGFjZWFfb2NjJGdlbnVzLCBmdW5jdGlvbih4KXt0YWJsZShDZXRhY2VhX29jYyRnZW51cylbeF19KQpDZXRhY2VhX29jY19hZ2dyZWdfZ2VuJGdlbnVzX2NvdW50IDwtIHNhcHBseShDZXRhY2VhX29jY19hZ2dyZWdfZ2VuJGdlbnVzLCBmdW5jdGlvbih4KXt0YWJsZShDZXRhY2VhX29jY19hZ2dyZWdfZ2VuJGdlbnVzKVt4XX0pCgpvbWVnYSA8LSAwLjMKZ2VudXNfY291bnQgPC0gQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayAlaW4lIGMoInNwZWNpZXMiLCAiZ2VudXMiKSxdJGdlbnVzX2NvdW50CmRlbnMgPC0gc2FwcGx5KDE6bWF4KGdlbnVzX2NvdW50KSwgZnVuY3Rpb24obil7IGV4cGVjdGVkX2Rpc3RyaWJ1dGlvbihuLCBvbWVnYSwgQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayAlaW4lIGMoInNwZWNpZXMiLCAiZ2VudXMiKSxdJGFnZV9jb21iaW5lZF9yYW5nZSkkdmFsdWUgfSkKZ2VudXNfY291bnRfY2F0ZWdvcmllcyA8LSB0YWJsZShnZW51c19jb3VudCkvYXMubnVtZXJpYyhuYW1lcyh0YWJsZShnZW51c19jb3VudCkpKSAgIyBOdW1iZXIgb2YgY2F0ZWdvcmllcyB3aXRoIDEsIDIsIDMsIC4uLiBvY2N1cnJlbmNlcyBvZiB0aGUgc2FtZSBnZW51cwoKIyBDb21wYXJlIHRoZSBpbml0aWFsIG9ic2VydmVkIGRpc3RyaWJ1dGlvbiB3aXRoIHRoZSB0aGVvcmV0aWNhbCBjdXJ2ZQpnZ3Bsb3QoQ2V0YWNlYV9vY2NbQ2V0YWNlYV9vY2MkYWNjZXB0ZWRfcmFuayAlaW4lIGMoInNwZWNpZXMiLCAiZ2VudXMiKSxdLCAKICAgICAgIGFlcyh4PWdlbnVzX2NvdW50LCAKICAgICAgICAgICB5PWdlbnVzX2NvdW50X2NhdGVnb3JpZXNbYXMuZmFjdG9yKGdlbnVzX2NvdW50KV0sIAogICAgICAgICAgIGZpbGw9YWNjZXB0ZWRfcmFuaykpICsKICBnZW9tX3BvaW50KCkgKwogIAogIGFubm90YXRlKCJsaW5lIiwgeCA9IDE6bWF4KGdlbnVzX2NvdW50KSwgeT0gZGVucwogICAgKm1heCgodGFibGUoZ2VudXNfY291bnQpL2FzLm51bWVyaWMobmFtZXModGFibGUoZ2VudXNfY291bnQpKSkpW2FzLmZhY3RvcihnZW51c19jb3VudCldKSAvbWF4KGRlbnMpKSsKICAKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJOdW1iZXIgb2Ygb2NjdXJyZW5jZXMgYnkgZ2VudXMiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZzEwIiwgbmFtZSA9ICJOdW1iZXIgb2YgY29ycmVzcG9uZGluZyBnZW5lcmEgKGxvZy1zY2FsZSkiKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSJPYnNlcnZlZCBkaXN0cmlidXRpb24iKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCkpICsKICBnZ3RpdGxlKCJDb21wYXJpc29uIGJldHdlZW4gZXhwZWN0ZWQgYW5kIG9ic2VydmVkIGRpc3RyaWJ1dGlvbnMgb2YgbnVtYmVyIG9mIG9jY3VycmVuY2VzIikKCmdlbnVzX2NvdW50X2FnZ3JlZyA8LSBDZXRhY2VhX29jY19hZ2dyZWdfZ2VuW0NldGFjZWFfb2NjX2FnZ3JlZ19nZW4kYWNjZXB0ZWRfcmFuayAlaW4lIGMoInNwZWNpZXMiLCAiZ2VudXMiKSxdJGdlbnVzX2NvdW50CmRlbnNfYWdncmVnIDwtIHNhcHBseSgxOm1heChnZW51c19jb3VudF9hZ2dyZWcpLCBmdW5jdGlvbihuKXsKICAgICBleHBlY3RlZF9kaXN0cmlidXRpb24obiwgb21lZ2EsIENldGFjZWFfb2NjX2FnZ3JlZ19nZW5bQ2V0YWNlYV9vY2NfYWdncmVnX2dlbiRhY2NlcHRlZF9yYW5rICVpbiUgYygic3BlY2llcyIsICJnZW51cyIpLF0kYWdlX2NvbWJpbmVkX3JhbmdlKSR2YWx1ZQogICAgfSkKCiMgTnVtYmVyIG9mIGNhdGVnb3JpZXMgd2l0aCAxLCAyLCAzLCAuLi4gb2NjdXJyZW5jZXMgb2YgdGhlIHNhbWUgZ2VudXMKZ2VudXNfY291bnRfY2F0ZWdvcmllc19hZ2dyZWcgPC0gdGFibGUoZ2VudXNfY291bnRfYWdncmVnKS9hcy5udW1lcmljKG5hbWVzKHRhYmxlKGdlbnVzX2NvdW50X2FnZ3JlZykpKQoKIyBOdW1iZXIgb2Ygb2NjdXJyZW5jZXMgYnkgY2F0ZWdvcnkKQ2V0YWNlYV9vY2NfYWdncmVnX2dlbiRnZW51c19jYXRlZ29yaWVzX2NvdW50IDwtIGFzLm51bWVyaWMoZ2VudXNfY291bnRfY2F0ZWdvcmllc19hZ2dyZWdbYXMuZmFjdG9yKENldGFjZWFfb2NjX2FnZ3JlZ19nZW4kZ2VudXNfY291bnQpXSkKCiMgQ29tcGFyZSB0aGUgY29ycmVjdGVkIG9ic2VydmVkIGRpc3RyaWJ1dGlvbiB3aXRoIHRoZSB0aGVvcmV0aWNhbCBjdXJ2ZQpnZ3Bsb3QoQ2V0YWNlYV9vY2NfYWdncmVnX2dlbltDZXRhY2VhX29jY19hZ2dyZWdfZ2VuJGFjY2VwdGVkX3JhbmsgJWluJSBjKCJzcGVjaWVzIiwgImdlbnVzIiksXSwgCiAgICAgICBhZXMoeD1nZW51c19jb3VudCwKICAgICAgICAgICB5PWdlbnVzX2NhdGVnb3JpZXNfY291bnQsCiAgICAgICAgICAgc2l6ZT1nZW51c19jYXRlZ29yaWVzX2NvdW50KSkgKwogIGdlb21fcG9pbnQoKSArCiAgCiAgYW5ub3RhdGUoImxpbmUiLCB4ID0gMTptYXgoZ2VudXNfY291bnRfYWdncmVnKSwgeT0gZGVuc19hZ2dyZWcKICAgICptYXgoKHRhYmxlKGdlbnVzX2NvdW50X2FnZ3JlZykvYXMubnVtZXJpYyhuYW1lcyh0YWJsZShnZW51c19jb3VudF9hZ2dyZWcpKSkpW2FzLmZhY3RvcihnZW51c19jb3VudF9hZ2dyZWcpXSkgL21heChkZW5zX2FnZ3JlZykpICsKICAKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJOdW1iZXIgb2Ygb2NjdXJyZW5jZXMgYnkgZ2VudXMiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gImxvZzEwIiwgbmFtZSA9ICJOdW1iZXIgb2YgY29ycmVzcG9uZGluZyBnZW5lcmEgKGxvZy1zY2FsZSkiKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSJPYnNlcnZlZCBkaXN0cmlidXRpb24iKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCkpICsKICBnZ3RpdGxlKCJDb21wYXJpc29uIGJldHdlZW4gZXhwZWN0ZWQgYW5kIG9ic2VydmVkIGRpc3RyaWJ1dGlvbnMgb2YgbnVtYmVyIG9mIG9jY3VycmVuY2VzLCBhZnRlciBhZ2dyZWdhdGluZyBpbiBnZW9wbGF0ZXMiKQoKZ2VudXNfY291bnRfYWdncmVnIDwtIENldGFjZWFfb2NjX2FnZ3JlZ19nZW5bQ2V0YWNlYV9vY2NfYWdncmVnX2dlbiRhY2NlcHRlZF9yYW5rICVpbiUgYygic3BlY2llcyIsICJnZW51cyIpLF0kZ2VudXNfY291bnQKZGVuc19hZ2dyZWcgPC0gc2FwcGx5KDE6bWF4KGdlbnVzX2NvdW50X2FnZ3JlZyksIGZ1bmN0aW9uKG4pewogICAgIGV4cGVjdGVkX2Rpc3RyaWJ1dGlvbihuLCBvbWVnYSwgQ2V0YWNlYV9vY2NfYWdncmVnX2dlbltDZXRhY2VhX29jY19hZ2dyZWdfZ2VuJGFjY2VwdGVkX3JhbmsgJWluJSBjKCJzcGVjaWVzIiwgImdlbnVzIiksXSRhZ2VfY29tYmluZWRfcmFuZ2UpJHZhbHVlCiAgICB9KQpnZW51c19jb3VudF9jYXRlZ29yaWVzX2FnZ3JlZyA8LSB0YWJsZShnZW51c19jb3VudF9hZ2dyZWcpL2FzLm51bWVyaWMobmFtZXModGFibGUoZ2VudXNfY291bnRfYWdncmVnKSkpICAjIE51bWJlciBvZiBjYXRlZ29yaWVzIHdpdGggMSwgMiwgMywgLi4uIG9jY3VycmVuY2VzIG9mIHRoZSBzYW1lIGdlbnVzCmBgYAoKJFx0byQgVGhlIGNvcnJlc3BvbmRhbmNlIGlzIG11Y2ggbGVzcyBpbXByb3ZlZCB0aGFuIHdpdGggc3BlY2llcyBhZ2dyZWdhdGlvbiBiZWNhdXNlIHNvbWUgZ2VuZXJhIGhhdmUgYSBsb3Qgb2Ygb2NjdXJyZW5jZXMgZHVlIHRvIHRoZWlyIGhpZ2ggbnVtYmVyIG9mIHNwZWNpZXMgc3BlY2llcyA6CgpgYGB7cn0KdGFibGUoZHJvcGxldmVscyhDZXRhY2VhX29jY19hZ2dyZWdfZ2VuWyhDZXRhY2VhX29jY19hZ2dyZWdfZ2VuJGFjY2VwdGVkX3JhbmsgJWluJSBjKCJzcGVjaWVzIiwgImdlbnVzIikpICYgKENldGFjZWFfb2NjX2FnZ3JlZ19nZW4kZ2VudXNfY291bnQ+MjUpLF0kZ2VudXMpKQpgYGAKCmBgYHtyIGZpZy5oZWlnaHQ9Nn0KY29uZGl0aW9ucyA8LSBDZXRhY2VhX29jYyRhY2NlcHRlZF9yYW5rICVpbiUgYygic3BlY2llcyIsICJnZW51cyIpCgpwMSA8LSBnZ3Bsb3QoQ2V0YWNlYV9vY2NbY29uZGl0aW9ucyxdLCBhZXMoeD0tYWdlX3J1bmlmKSkgKwogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMC41LCBhbHBoYT0wLjUsIGZpbGw9TkEsIGNvbD0icmVkIikgKwogIHhsaW0oLW1heChDZXRhY2VhX29jY1tjb25kaXRpb25zLF0kYWdlX3J1bmlmKS0xLCAxKSArCiAgeWxpbSgwLCA4MCkgKwogIHRoZW1lX3ZvaWQoKQoKcDIgPC0gZ2dwbG90KENldGFjZWFfb2NjX3NhbXBsZWQsIGFlcyh4PS1hZ2VfcnVuaWYpKSArCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjUsIGFscGhhPTAuNSwgZmlsbD0iYmx1ZSIpICsKICB4bGltKC1tYXgoQ2V0YWNlYV9vY2NbY29uZGl0aW9ucyxdJGFnZV9ydW5pZiktMSwgMSkgKwogIHlsaW0oMCwgODApICsKICB0aGVtZV92b2lkKCkKCnAzIDwtIGdncGxvdChDZXRhY2VhX29jY19hZ2dyZWdfZ2VuW0NldGFjZWFfb2NjX2FnZ3JlZ19nZW4kYWNjZXB0ZWRfcmFuayAlaW4lIGMoInNwZWNpZXMiLCAiZ2VudXMiKSxdLCBhZXMoeD0tYWdlX3J1bmlmKSkgKwogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMC41LCBhbHBoYT0wLjUsIGZpbGw9ImdyZWVuIikgKwogIHhsaW0oLW1heChDZXRhY2VhX29jY1tjb25kaXRpb25zLF0kYWdlX3J1bmlmKS0xLCAxKSArCiAgeWxpbSgwLCA4MCkgKwogIHRoZW1lX3ZvaWQoKQoKcDEgKyBhbm5vdGF0aW9uX2N1c3RvbShnZ3Bsb3RHcm9iKHAyKSkgKyBnZ3RpdGxlKCJJbml0aWFsIG9jY3VycmVuY2VzIGRpc3RyaWJ1dGlvbiAocmVkKSBhbmQgY29tcGFyaXNvbiBhZnRlciBzdWItc2FtcGxpbmcgKGJsdWUpIikKCnAxICsgYW5ub3RhdGlvbl9jdXN0b20oZ2dwbG90R3JvYihwMykpICsgZ2d0aXRsZSgiSW5pdGlhbCBvY2N1cnJlbmNlcyBkaXN0cmlidXRpb24gKHJlZCkgYW5kIGNvbXBhcmlzb24gYWZ0ZXIgYWdncmVnYXRpbmcgaW4gZ2VvcGxhdGVzIChncmVlbikiKQoKcDEgKyBhbm5vdGF0aW9uX2N1c3RvbShnZ3Bsb3RHcm9iKHAyKSkgKyBhbm5vdGF0aW9uX2N1c3RvbShnZ3Bsb3RHcm9iKHAzKSkgKyBnZ3RpdGxlKCJJbml0aWFsIG9jY3VycmVuY2VzIGRpc3RyaWJ1dGlvbiAocmVkKSBhbmQgY29tcGFyaXNvbiBhZnRlciBzdWItc2FtcGxpbmcgKGJsdWUpIG9yIGFnZ3JlZ2F0aW5nIGluIGdlb3BsYXRlcyAoZ3JlZW4pIikKYGBgCgokXHRvJCBEZWxpbWl0aW5nIGJ5IGdlb2xvZ2ljYWwgcGxhdGVzICgrIGFnZSkgaW5zdGVhZCBvZiBjb3VudHJpZXMgKCsgYWdlKSBsZWFkcyB0byBzaW1pbGFyIGRpc3RyaWJ1dGlvbnMsIHdpdGggYSBiaXQgbW9yZSBvY2N1cnJlbmNlcywgc28gd2Ugd2lsbCBrZWVwIGl0LgoKYGBge3J9CndyaXRlLnRhYmxlKENldGFjZWFfb2NjX2FnZ3JlZ19nZW5bQ2V0YWNlYV9vY2NfYWdncmVnX2dlbiRhY2NlcHRlZF9yYW5rICVpbiUgYygic3BlY2llcyIsICJnZW51cyIpLCBjKCJtaW5fbWEiLCAibWF4X21hIildLAogICAgICAgICAgICBmaWxlPSJkYXRhLWNldGFjZWFucy9DZXRhY2VhX29jY3VycmVuY2VzX21pbl9tYXhfYWdlX2dlbmVyYV9jb3JyZWN0ZWQuY3N2Iiwgc2VwPSIsIiwgcm93Lm5hbWVzPUZBTFNFLCBjb2wubmFtZXM9RkFMU0UpCmBgYAoKIyBDb25jbHVzaW9ucwoKQWNoaWV2ZW1lbnRzIDoKCiAgLSBJdCBzZWVtcyBwb3NzaWJsZSB0byBhZGVxdWF0ZWx5IHJlZHVjZSB0aGUgYWJ1bmRhbmNlIGJpYXMgYnkgc3Vic2FtcGxpbmcgdGhlIG1vc3QgY29uY2VudHJhdGVkIGludGVydmFscyAkXHRvJCAqKnNwZWNpZXMgb25seSoqCiAgLSBVc2luZyBjb21iaW5lZCByYW5nZXMgYnkgc3BlY2llcyBhcHBlYXJzIHRvIGJlIG1vcmUgcm9idXN0ICRcdG8kICoqdG8gYmUgY29uZmlybWVkKioKICAtIFZlcnkgcmVjZW50IHNhbXBsZXMgbWF5IGhhdmUgYmVlbiBkYXRlZCB3aXRoIGEgbW9yZSBwcmVjaXNlIG1ldGhvZCBhbmQgY29udGFpbiBtdWNoIG1vcmUgZm9zc2lscywgc28gdGhleSBzaG91bGQgYmUgcmVtb3ZlZCBvciB0cmVhdGVkIHNlcGFyYXRhZGVseSAkXHRvJCAqKmFkZGl0aW9uYWwgaW5mb3JtYXRpb24gbmVlZGVkKioKCk9wZW4gcXVlc3Rpb25zIDoKCiAgLSBXaGF0IGFib3V0IG90aGVyIGFjY2VwdGVkIHJhbmtzID8KICAgIDEuIFRoZSBwcm9ibGVtIGlzIHRoYXQgZGlmZmVyZW5jZXMgaW4gdGhlIG51bWJlciBvZiBvY2N1cnJlbmNlcyBhdCBoaWdoZXIgcmFua3MgY291bGQgYmUgZHVlIHRvIGRpZmZlcmVuY2VzIGluIGluZGl2aWR1YWwgYWJ1bmRhbmNlcyBpbnNpZGUgc3BlY2llcyBvciBkdWUgdG8gZGlmZmVyZW5jZXMgaW4gdGhlIG51bWJlciBvZiBzcGVjaWVzIGluc2lkZSB0aGF0IGdyb3VwLgogICAgMi4gQSBzb2x1dGlvbiBjb3VsZCBiZSB0byBsb29rIGF0IHRoZSBudW1iZXIgb2Ygc3BlY2llcyBieSBncm91cCBiYXNlZCBvbiB0aGUgaW5kaWNhdGVkIHNwZWNpZXMsIGFuZCBpbmNsdWRlIGl0IGluIHRoZSBiaWFzIGNvcnJlY3Rpb24gOiBob21vZ2VuZWl6aW5nIHRoZSAqbnVtYmVyIG9mIG9jY3VycmVuY2VzIC8gdGltZSB1bml0IC8gbnVtYmVyIHNmIHNwZWNpZXMgaW4gdGhlIGdyb3VwKiAkXHRvJCAqKmFkZGl0aW9uYWwgZGF0YSByZXF1aXJlZCoqIChyYW5rcyBjbGFzc2lmaWNhdGlvbikKICAtIFdoeSBkbyBtb3N0IG9jY3VycmVuY2VzIG1pc3MgYSBsYXRlIHN0cmF0aWdyYXBoaWMgbGltaXQgPwogIC0gU29tZSBvY2N1cnJlbmNlcyBoYXZlIHZlcnkgaHVnZSB0aW1lIGludGVydmFscyAkXHRvJCAqKldhcyBpcyBhIGdvb2QgaWRlYSB0byByZW1vdmUgdGhvc2UgPjEwTXkgPyBTaG91bGQgd2UgcmVtb3ZlIG1vcmUgb2YgdGhlbSAoPjVNeSkgPyoqCgoKICAgIAogICAg